• 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();
        }
    }
    
  • 相关阅读:
    字段操作
    数据操作
    表操作
    数据库操作
    如何连接mysql
    mysql新增用户和修改用户密码
    表和库和服务器的关系
    MySql的复合类型
    yum软件源
    常用正则表达式
  • 原文地址:https://www.cnblogs.com/zut-syp/p/13570754.html
Copyright © 2020-2023  润新知