java学习之路03-java反射

    技术2022-07-11  114

    java反射

    什么是反射基本语法获取Class对象获取Constructor对象获取Field对象获取Method对象 简单使用 本节学习java反射机制的一些基本语法和一些简单的使用

    什么是反射

    在运行状态时,我们可以动态的获取任何一个类的字节码文件(.class文件)对象,通过这个字节码文件对象获取这个类的方法对象,构造器对象,成员变量对象等等信息。 一个类的全部组成对应一个个对象,这就是反射机制。

    基本语法

    获取Class对象

    获取类对象有3种方式

    通过字符串获取类对象: Class cls = Class.forName(包名.类名) 通过类获取类对象: Class cls =MyClass.class 通过对象获取类对象: Class cls =new MyClass().MyClass()

    获取Constructor对象

    获取所有public构造器对象,返回构造器数组 Constructor[] constructors = cls.getConstructors(); 获取所有的构造器对象(包括:private、protected、default、public),返回构造器数组 Constructor[] constructors = cls.getDeclaredConstructors(); 通过参数获取public构造器对象,返回一个构造器对象 Constructor constructor = cls.getConstructor(null,int.class); 通过参数获取构造器对象(包括:private、protected、default、public),返回一个构造器对象 Constructor constructor = cls.getDeclaredConstructor(null,Integer.class);

    那么如何使用获取到的构造器来创建一个对象呢? 如果获取的方法在当前是有权限可以访问的,则可以直接使用: 作用域:

    作用域当前类同一package子孙类其他packagepublic√√√√protected√√√×default√√××private√××× MyClass myClass = (MyClass) constructor.newInstance();

    如果无法访问时执行则会抛IllegalAccessException异常。 那么我们可以通过setAccessible方法进行抑制java语言访问检查,不会抛异常,可以正常执行:

    constructor.setAccessible(true); MyClass myClass = (MyClass) constructor.newInstance();

    获取Field对象

    获取所有成员变量(public,包括父类继承的字段),返回成员变量列表 Field[] fields = cls.getFields(); 获取所有成员变量(private、protected、default、public,不包括继承的字段),返回成员变量列表 Field[] fields = cls.getDeclaredFields(); 获取指定名称的成员变量(public,包括父类继承的字段),返回一个成员变量 Field field = cls.getField("a"); 获取指定名称的成员变量(private、protected、default、public,不包括继承的字段),返回一个成员变量 Field field = cls.getDeclaredField("a");

    得到成员变量后,给一个MyTest对象设置成员变量的值并且获取该成员变量的值:

    //通过构造器new一个对象myClass MyClass myClass = (MyClass) constructor.newInstance(); //如果无权限访问则抑制java语言检查 field.setAccessible(true); field.set(myClass,3); field.get(myClass);

    获取Method对象

    获取所有成员方法(public,包括父类继承的方法),返回成员方法列表 Method[] methods = cls.getMethods(); 获取所有成员方法(private、protected、default、public,不包括继承的方法),返回成员方法列表 Method[] methods = cls.getDeclaredMethods(); 获取指定名称和参数的成员方法(public,包括父类继承的方法),返回一个成员方法 Method method = cls.getMethod("fun",null); 获取指定名称和参数的成员方法(private、protected、default、public,不包括继承的方法),返回一个成员方法 Method method = cls.getDeclaredMethod("fun",null,int.class);

    使用成员方法:

    //如果无权限访问则抑制java语言检查 method.setAccessible(true); //如果是普通成员变量,则需要传入一个对象 //如果是无参方法,那么第二个参数可以不传或者传null method.invoke(myClass); method.invoke(myClass,null); //正常传参调用方法 method.invoke(myClass,1); //如果是静态方法,第一个参数可以传null method.invoke(null,1);

    简单使用

    反射是动态获取类中的各种对象对其进行操作,那么我们可以基于一些配置文件动态的执行一些代码: 在配置文件中配置属性: class.name = 包名.类名 method.name = 方法名

    然后在代码中读取配置文件并且执行相关配置:

    @Value("${class.name}") private String className; @Value("${method.name}") private String methodName; Class cls = Class.forName(className); Method method = cls.getMethod(methodName); Constructor constructor = cls.getConstructor(); Object obj = constructor.newInstance(); method.invoke(obj); 反射可以直接越过编译期间的泛型检查 List<String> list = Lists.newArrayList(); list.add("1"); Class cls = list.getClass(); Method method = cls.getMethod("add",Object.class); method.invoke(list,1);
    Processed: 0.011, SQL: 9