重新复写下反射的知识
反射:动态的获取指定的类以及动态的调用类中的内容
应用场景:该应用程序已写好,后期出现的接口子类无法直接在该应用程序中用new创建对象. 既然子类不确定,可以通过对外提供配置文件的形式,将不确定的信息存储到配置文件中即可.该程序只要之前写好如何读取配置文件信息即可.如果存储了指定的子类名,就根据具体的名称找到该类并进行加载和对象的创建,这些动作都是在前期定义软件时写好的,没有类之前就将创建对象的动作完成了,这就是动态的获取指定的类,并使用类中的功能. 反射技术的出现大大的提高了程序的扩展性
获取字节码文件方式:
1.通过Object类中的getclass(); 但是前提必须有指定类,并对该类进行对象的创建,才可以调用getclass方法
ps: 创建两个对象,分别通过getclass()获取字节码对象,此时clazz1 == clazz2,应为在程序中的字节码对象是唯一的.
2.使用的任意数据类型的一个静态成员class.所有的数据类型都具备的一个属性类.class 好处是不用new对象,但是还是需要具体的类
3. Class.getName(String 类名) 类名必须包含包名
newInstance()创建Class对象所表示的类的一个新实例.
通常反射的类都会有提供空参数的构造函数
没有对应的构造函数,会报InstantiationException
如果有提供但是权限不够(不是public)会报IllegalAccessExcrption
如果通过指定的构造函数初始化对象:
1.获取字节码文件对象
2.获取给定的构造函数
getConstructor(Class<?>... parameterTypes) 假如带参数的构造函数的参数为String和int ,那么就是Constructor cons = getConstruction(String.class, int.class);
3. 通过构造函数初始化对象 Object obj= cons.newInstance("hah", 12); 传的参数即为new对象时传的实参
获取字段:
getField() 获取公有字段
getDeclaredField(String name) 可获取全部字段
如果直接set字段的值,并且字段是私有的将会报IllegalAccessExcrption异常. 可通过其父类AccessiableObject的方法,setAccessiable(true),可取消权限的控制.即暴力访问
获取方法:
getMethod(String name, Class<?>... parameterTypes) 如果参数为空 传null
调用:invoke(Object obj, Object... args) 静态方法 对象传null