zoukankan      html  css  js  c++  java
  • JavaSE学习笔记

    概述

    • 反射是一种强大的工具,可以用来编写能够动态操纵 Java 代码的程序,通过反射机制我们可以操作字节码文件。反射机制将类的各个部分封装成了对象,在程序运行的过程中我们可以操作这些对象(在操作一个类对象的时候我们可以操作其方法成员变量等)。这样可以使得程序解耦,提高了程序的可扩展性。

    Java 代码的三个阶段

    • 源代码阶段:编写类文件,然后添加成员变量,成员方法等,代码编译后生成字节码文件,此时代码还未被加载进内存。
    • Class 类对象阶段:Class 类对象使用类加载器将字节码文件加载进内存,此时内存中就会产生一个唯一的 Class 类对象来标识这个类中的各项信息,Class 类对象中又包含了描述成员变量的 Field 对象、描述构造方法的 Constructor 对象和描述成员方法的 Method 对象。
    • 运行时阶段:new 一个新的类对象。

    Class

    • 在程序运行的时候,系统始终为所有的对象维护一个运行时的类型标识,这个信息会跟踪每一个对象所属的类,我们使用 Java 中的 Class 类就可以访问这些被记录的信息。

    获取 Class 对象的三种方式

    • Class.forName("全类名"):将字节码文件加载进内存,配置文件常用
    public class Main {
        public static void main(String[] args) throws ClassNotFoundException {
            Class cls = Class.forName("java.lang.String");
            System.out.println(cls);//class java.lang.String
        }
    }
    
    • 类名.class:常用于参数的传递
    public class Main {
        public static void main(String[] args) throws ClassNotFoundException {
            Class cls = Class.forName("java.lang.String");
            Class cls1 = String.class;
            System.out.println(cls.hashCode());//460141958
            System.out.println(cls1);//class java.lang.String
        }
    }
    
    • 对象.getClass():常用于获取对象字节码
    public class Main {
        public static void main(String[] args) throws ClassNotFoundException {
            Class cls = Class.forName("java.lang.String");
            Class cls1 = String.class;
            String str = "";
            Class cls2 = str.getClass();
            //字节码文件在内存中只被加载一次
            //不管使用什么方式获取到的Class对象都是同一个
            System.out.println(cls.hashCode());//460141958
            System.out.println(cls1.hashCode());//460141958
            System.out.println(cls2);//class java.lang.String
        }
    }
    

    Class 类常用 API

    • 获取 public 修饰的成员变量
    //获取 public 修饰的成员变量
    public class Main {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
            Class cls = Class.forName("java.lang.String");
            Field[] fields = cls.getFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }
    
            Field field = cls.getField("CASE_INSENSITIVE_ORDER");
            System.out.println(field.getName());
        }
    }
    
    
    //获取所有的成员变量
    public class Main {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
            Class cls = Class.forName("java.lang.String");
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }
    
            Field field = cls.getDeclaredField("hash");
            System.out.println(field.getName());
        }
    }
    
    • 获取构造函数
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            //得到所有公共的构造函数对象
            Constructor[] constructors = cls.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
    
            //得到特定的公共构造函数对象
            Constructor constructor = cls.getConstructor(String.class);
            System.out.println(constructor);
        }
    }
    
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            //得到所有的构造函数对象
            Constructor[] constructors = cls.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
    
            //得到特定的构造函数对象
            Constructor constructor = cls.getDeclaredConstructor(String.class);
            System.out.println(constructor);
        }
    }
    
    • 获取成员方法
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            //获取所有公共的成员方法
            Method[] methods = cls.getMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
    
            //获取特定的公共的成员方法
            System.out.println("-------");
            Method method = cls.getMethod("toLowerCase", Locale.class);
            System.out.println(method);
        }
    }
    
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            //获取所有的成员方法
            Method[] methods = cls.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
    
            //获取特定的成员方法
            System.out.println("-------");
            Method method = cls.getDeclaredMethod("lastIndexOfSupplementary", int.class, int.class);
            System.out.println(method);
        }
    }
    
    • 有关 Class 类的 API
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            System.out.println(cls.getName());//java.lang.String
            System.out.println(cls.getSimpleName());//String
    
            //获取父类
            Class superclass = cls.getSuperclass();
            System.out.println(superclass);//class java.lang.Object
            System.out.println(superclass.isInterface());//false
    
            //获取包对象
            Package aPackage = cls.getPackage();
            System.out.println(aPackage.getName());//java.lang
    
        }
    }
    

    Constructor

    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            //得到所有的构造函数对象
            Constructor[] constructors = cls.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
                //方法名
                System.out.println(constructor.getName());
                //修饰符
                System.out.println(Modifier.toString(constructor.getModifiers()));
                //参数类型
                Class[] parameterTypes = constructor.getParameterTypes();
                for (Class parameterType : parameterTypes) {
                    System.out.print(parameterType.getName() + " ");
                }
                System.out.println();
                System.out.println("-------------------------------------");
            }
        }
    }
    
    
    //创建对象
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = String.class;
            String str = (String) cls.newInstance();
        }
    }
    

    Field

    public class Main {
        public static void main(String[] args) throws Exception {
            String str = "1111";
            Class cls = Class.forName("java.lang.String");
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field);
                System.out.println(Modifier.toString(field.getModifiers()));
                System.out.println(field.getType().getSimpleName());
                System.out.println(field.getName());
                //System.out.println(field.get(str));
                System.out.println("-----------------------------------------------");
            }
    
        }
    }
    //为对象的成员变量设置值
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = String.class;
            String str = (String) cls.newInstance();
            Field field = cls.getDeclaredField("value");
            //不是公共的成员变量是需要暴力反射,默认只能修改非公共成员变量
            field.setAccessible(true);
            System.out.println(field);
            System.out.println(field.get(str));//[C@4554617c
            System.out.println(str);//
            field.set(str, new char[]{'1', '1'});
            System.out.println(field.get(str));//[C@74a14482
            System.out.println(str);//11
        }
    }
    
    

    Method

    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = Class.forName("java.lang.String");
    
            //获取所有的成员方法
            Method[] methods = cls.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method);
                System.out.println(Modifier.toString(method.getModifiers()));
                System.out.println(method.getReturnType().getSimpleName());
                Class<?>[] parameterTypes = method.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    System.out.println(parameterType.getSimpleName());
                }
                //是否有可变参数
                System.out.println(method.isVarArgs());
                System.out.println(method.getName());
                System.out.println("-------------------------");
            }
        }
    }
    
    //执行类方法
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cls = String.class;
            String str = (String) cls.newInstance();
            Field field = cls.getDeclaredField("value");
            field.setAccessible(true);
    
            field.set(str, new char[]{'1', '1'});
    
            Method method = cls.getDeclaredMethod("length");
            System.out.println(method.invoke(str));
    
        }
    }
    

    配置文件操作类

    配置文件

    className = java.lang.String
    methodName = length
    fieldName = value
    

    Properties + IO + 反射

    public class Main {
        public static void main(String[] args) throws Exception {
            Properties properties = new Properties();
    
            //方式一:利用当前类获取流,配置文件需要在src目录下
            ClassLoader classLoader = Main.class.getClassLoader();
            InputStream is = classLoader.getResourceAsStream("pro.properties");
            properties.load(is); //要记得关闭流
    
            //方式二:首先获取文件路径,然后根据路径创建输入流
            //配置文件需要在根路径下
    //        String path = Thread.currentThread().getContextClassLoader().getResource("pro.properties").getPath();
    //        //System.out.println(path);
    //        FileReader reader = new FileReader(path);
    //        properties.load(reader);
    
            Class cls = Class.forName(properties.getProperty("className"));
            Object o = cls.newInstance();
            Field field = cls.getDeclaredField(properties.getProperty("fieldName"));
            field.setAccessible(true);
            field.set(o, new char[]{'a', 'b'});
            System.out.println(field.get(o));
    
            Method method = cls.getDeclaredMethod(properties.getProperty("methodName"));
            System.out.println(method.invoke(o));
        }
    }
    

    ResourceBundle + 反射

    public class Main {
        public static void main(String[] args) throws Exception {
            //资源绑定器,配置文件需要放在根路径下
            ResourceBundle bundle = ResourceBundle.getBundle("pro");
    
            Class cls = Class.forName(bundle.getString("className"));
            Object o = cls.newInstance();
            Field field = cls.getDeclaredField(bundle.getString("fieldName"));
            field.setAccessible(true);
            field.set(o, new char[]{'a', 'b'});
            System.out.println(field.get(o));
    
            Method method = cls.getDeclaredMethod(bundle.getString("methodName"));
            System.out.println(method.invoke(o));
        }
    }
    

    反射方式反编译类框架

    配置文件

    className = java.util.ResourceBundle 
    

    测试代码

    public class Main {
        public static void main(String[] args) throws ClassNotFoundException {
            //资源绑定器,配置文件需要放在根路径下
            ResourceBundle bundle = ResourceBundle.getBundle("pro");
    
            Class<?> cls = Class.forName(bundle.getString("className"));
            Package aPackage = cls.getPackage();
            //包
            if (aPackage != null) System.out.println("package " + aPackage.getName());
            System.out.println();
            //修饰符
            System.out.print(Modifier.toString(cls.getModifiers()) + " ");
            //类名
            System.out.print(cls.getSimpleName() + " ");
            //父类
            Class<?> superclass = cls.getSuperclass();
            if (!superclass.equals(Object.class)) {
                System.out.print( "extends " + superclass.getSimpleName() + " ");
            }
            //接口
            Class<?>[] interfaces = cls.getInterfaces();
            StringBuilder _interfaces = new StringBuilder();
            if(interfaces.length == 0) {
                _interfaces.append("");
            } else {
                _interfaces.append(" implements ");
            }
            for (int i = 0; i < interfaces.length; i++) {
                _interfaces.append(interfaces[i].getSimpleName());
                if (i != interfaces.length - 1) {
                    _interfaces.append(", ");
                } else {
                    _interfaces.append(" ");
                }
            }
            System.out.println(_interfaces + "{");
    
            System.out.println();
            //获取成员变量
            getDeclaredFields(cls);
            //获取构造方法
            getDeclaredConstructors(cls);
            //获取成员方法
            getMethods(cls);
    
            System.out.println("}");
        }
    
        private static void getDeclaredFields(Class<?> cls) {
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                System.out.print("	");
                //修饰符
                System.out.print(Modifier.toString(field.getModifiers()) + " ");
                //数据类型
                System.out.print(field.getType().getSimpleName() + " ");
                //变量名
                System.out.println(field.getName() + ";");
                //System.out.println(field);
                //System.out.println("----------------");
            }
            System.out.println();
        }
    
        private static void getDeclaredConstructors(Class<?> cls) {
            Constructor<?>[] constructors = cls.getDeclaredConstructors();
            for (Constructor<?> constructor : constructors) {
                //修饰符
                System.out.print("	");
                if (constructor.getModifiers() != 0)
                    System.out.print(Modifier.toString(constructor.getModifiers()) + " ");
                //方法名
                System.out.print(cls.getSimpleName() + "(");
                //参数
                Class<?>[] typeParameters = constructor.getParameterTypes();
                StringBuilder _typeParameters = new StringBuilder();
                for (int i = 0; i < typeParameters.length; i++) {
                    if (i != 0) {
                        _typeParameters.append(", ");
                    }
                    _typeParameters.append(typeParameters[i].getSimpleName());
                }
                System.out.println(_typeParameters + "){};");
                //System.out.println(constructor);
                //System.out.println("---------------------------");
            }
            System.out.println();
        }
    
        private static void getMethods(Class<?> cls) {
            Method[] methods = cls.getMethods();
            for (Method method : methods) {
                System.out.print("	");
                //修饰符
                System.out.print(Modifier.toString(method.getModifiers()) + " ");
                //返回值
                System.out.print(method.getReturnType().getSimpleName() + " ");
                //方法名
                System.out.print(method.getName() + "(");
                //参数
                Class<?>[] parameterTypes = method.getParameterTypes();
                StringBuilder _parameterTypes = new StringBuilder();
                for (int i = 0; i < parameterTypes.length; i++) {
                    if (i != 0) {
                        _parameterTypes.append(", ");
                    }
                    _parameterTypes.append(parameterTypes[i].getSimpleName());
                }
                System.out.println(_parameterTypes + "){};");
                //System.out.println(method);
                //System.out.println("------------------------");
            }
            System.out.println();
        }
    }
    
  • 相关阅读:
    datanode报错Problem connecting to server
    使用命令查看hdfs的状态
    Access denied for user root. Superuser privilege is requ
    ElasticSearch默认的分页参数 size
    SparkStreaming Kafka 维护offset
    【容错篇】Spark Streaming的还原药水——Checkpoint
    251 Android 线性与相对布局简介
    250 Android Studio使用指南 总结
    249 如何解决项目导入产生的中文乱码问题
    248 gradle更新问题
  • 原文地址:https://www.cnblogs.com/zut-syp/p/13570754.html
Copyright © 2011-2022 走看看