一、Java反射
Reflection 在运行时看透class
功能:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法
直接获取类的信息,通过方法间接获取对象信息。
二、反射API
Class类:代表一个类
Field类:代表类的一个成员变量
Method类:代表类的一个方法
Constructor类:代表类的一个构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
三、Class类
Class类的构造方法为私有,只有Java虚拟机可以创建Class对象。
Class类是反射的根源
类对象的获取:
Class<?> c = 对象.getClass() : 获取对象的类对象
Class<?> s = c.getSuperclass() : 获取类对象的父类对象
int[].class : 整型数组的类对象
四、使用反射入口
要想使用反射,首先获取需要操作类的类对象:
获取类对象:
Class.forName() / 操作类.class / 实例.getClass()
Class<?> classType = Class.forName("完整的类名");
类的任意一个实例都会对应于同一个Class对象。每个类都有一个Class对象
五、生成实例:newInstance()
Object myInstance = classType.newInstance(); //不带参数的实例化
六、获取方法
获取类的所有方法:
Method[] classMethods = classType.getDeclaredMethods(); 获取类中声明的所有方法
获取类的特定方法(public)
Method specificMethod = classType.getMethod("方法名",方法参数Class对象组成的数组)
例:classType.getMethod("add",new Class[]{int.class,int.class});
七、调用方法:method.invoke
Object result = specificMethod.invoke(调用的对象,参数组成的Object数组);
result:返回值
例:Object result = specificMethod.invoke(myInstance,new Object[]{1,3});
八、获取类的成员变量:.getDeclaredFields();
Field[] fields = classType.getDeclaredFields();
获取成员变量的名字:field.getName
获取成员变量的类对象:field.getType
getType():
//Returns a Class object that identifies the declared type for the field represented by this Field object.
获取成员变量的get/set方法:
String name = field.getName();
String getMethodName = "get"+name.subString(0,1).toUpperCase+name.subString(1);
String setMethodName = "set"+name.subString(0,1).toUpperCase+name.subString(1);
Method getMethod = classType.getMethod(getMethodName,new Class[]{});
Method setMethod = classType.getMethod(setMethodName,new Class[]{field.getType()});
八、通过构造方法生成对象:.getConstructor()
需要构造方法定义为public
Constructor construc = classType.getConstructor(new Class[]{});
//获取无参的构造方法
Object object = construc.newInstance(new Object[]{});
//通过无参的构造方法生成对象
上面两行代码相当于 Object object = classType.newInstance();
获取有参的构造方法
Constructor cons2 = classType.getConstructor(new Class[]{int.class,int.class});//参数:构造方法参数的类对象数组
Object object2 = cons2.newInstance(new Object[]{13,30});
//通过传入参数组成的Object数组生成实例。
九、使用反射调用对象的私有方法
Method继承AccessibleObject
.getMethod 只能返回public方法
.getDeclaredMethod 返回声明过的方法
Method method = classType.getDeclaredMethod("方法名",new Class[]{...});
method.setAccessible(true);//压制java的访问控制检查。
method.invoke(调用的对象,new Object[]{...});
十、使用反射访问对象的私有成员变量
Field继承AccessibleObject
.getField 只能返回public成员变量
.getDeclaredField 返回声明过的成员变量
Field field = classType.getDeclaredField("成员变量名");
field.setAccessible(true);//压制java对访问修饰符检查,如private...。
field.set(调用的对象,设置的值);
field.get(调用的对象)
十一、Array类:生成实例数组
创建一维数组
Class<?> classType = Class.forName("java.lang.String");
Object array = Array.newInstance(classType,10);
//生成一个对象数组,元素个数为10个
Array.set(array,5,"hello");//设置数组元素的值,index为5
String str = (String)Array.get(array,5);//获取数组元素,需要强制转换。
创建二维数组
int[] dimension = new int[]{2,3}; //用一个一维数组维度声明:行:2,列:3
Object array = Array.newInstance(Integer.TYPE,dimension);
Object arrayObject = Array.get(array,0);//获取第一行
Array.setInt(arrayObject,1,12);//设置第一行第两列的元素值为12
int[][] arrayCast = (int [][])array;//强制类型转换
System.out.println(arrayCast[0][1]);//打印出12
//三维数组类似,到最后一维时.set设置元素值。
说明:
Integer.TYPE 与 Integer.class
Integer.TYPE 返回 int.class
Integer.class 返回 Integer类对应的类对象 Integer.class
安卓中什么时候使用反射
功能清单清单文件:配置应用组件的全类名 布局文件:视图标签 显式意图:指定类的Class对象 调用系统隐藏的API ….