外观
Java反射
1.定义
反射是Java被称为动态语言的关键,反射允许程序在执行期间借助于ReflectionAPI取得任何类的内部信息,并直接操作任意内部属性的方法
2.反射的作用
1.在运行时构造任意一个类的对象
2.在运行时获取任意一个类所具有的成员变量和方法
3.在运行时调用任意一个对象的方法和属性
4.观察类的内部成员
5.不使用new创建类的实例成员
3.如何使用
一个重要的类-Class
用来描述类的类
想要反射,必须先得到一个Class的对象
获取对象的四种方式
1.通过类属性。例Class class1 = String.class
2.通过对象的getCalss()方法。例"aaa".getClass()
3.反射中包装类的TYPE属性表示它对应的基本数据类型
例:Class class2 = Integer.TYPE
4.通过Class.forName(String classname)方法
例:Class class3 = Class.forName("类名")
获取对象的方式
1.new
2.工厂方法
3.clone()方法
4.反序列化
5.常量
6.枚举
7.反射
反射常用的方法
1.Class
1.Class类的静态成员方法,通过完整的包名.类名获取对应.class文件的Class对象
Class Class.forName(String packageNameAndClassName);
2.通过类名.class方法,获取对应的Class类对象,通常用于方法的参数类型
Class 类名.class;
3.通过类对象获取对应.class的Class类对象,方法参数,或者说数据类型判断
Class 类对象.getClass();
2.Constructor
1.获取当前Class类对象对应Java文件中,所有【public修饰构造方法的类对象数组】
public Constructor[] getConstructors();
2.获取当前Class类对象对应Java文件中,所有【构造方法的类对象数组】,包括私有化构造方法。
public Constructor[] getDeclaredConstructors();
3.根据指定的数据类型,来选择对应的构造方法,这里有且只能获取获取类内的指定数据类型public修饰构造方法类对象
public Constructor getConstructor(Class...initArgumentTypes);
4.根据指定的数据类型,来选择对应的构造方法,这里可能会抛出异常。这里可以获取指定参数类型私有化构造方法和非私有化构造方法
public ConstructorgetDeclaredConstructor(Class...initArgumentTypes);
5.通过Constructor对象来调用,传入当前构造方法所需创建对象的初始化参数,创建对象
Object newInstance(Object... initArguments);
6.给予通过暴力反射得到的非公开权限成员变量、成员方法、构造方法操作权限
setAccessible(boolean flag);
2.Method
1.获取类内所有public修饰的成员方法,包括从父类继承而来的public修饰方法
Method[] getMethods();
2.获取类内所有成员方法,但是不包括从父类继承而来的方法
Method[] getDeclaredMethods();
3.根据指定的方法名和对应的参数类型,获取对应的public修饰的成员方法,包括从父类继承得来的
Method getMethod(String methodName, Class...parameterTypes);
4.根据指定的方法名和对应的参数类型,获取对应的成员方法,包括私有化成员方法,但是不包括从父类继承而来的方法
Method getDeclaredMethod(String methodName, Class... parameterTypes);
5.通过Method类对象调用,执行对应的方法,需要的参数
Object invoke(Object obj, Object... arguments);
3.Field
1.获取类内所有public修饰的成员变量
Field[] getFields();
2.获取类内所有成员变量,包括私有化成员方法
Field[] getDeclaredFields();
3.获取指定变量名的成员变量对象,要求是public修饰的成员变量
Field getField(String fieldName);
4.获取指定变量名的成员变量对象,包括private私有化修饰的成员变量
Field getDeclaredField(String fieldName);
5.设置指定调用者中对应成员变量的数据
void set(Object obj, Object value);
6.获取指定调用者中指定成员变量的数据
Object get(Object obj);
总结
1.方法看似多,记起来很有规律,Constructor、Method、Field获取全部和获取指定共6个,暴力反射获取在这些方法基础上加上Declared,又是6个; 2.成员变量和成员方法在使用时需要提供使用者,因为每个对象都不一样; 3.暴力反射获取的如果要使用就调用setAccessible方法赋值true; 4.很多方法使用时都会抛出异常,都是找不到指定内容、参数类型不匹配等。