反射

正常方式:引入需要的“包.类”名称 —> 通过new实例化 —>取得实例化对象
反射方式:实例化对象—>getClass()方法—>得到完整的“包.类”名称

Class类是反射的源头

实例化Class类对象方法有三种:

1、通过forName()方法,需要完整的包名加类名
示例代码:Class> c1 = Class.forName(“com.cong.Student”)
2、类.class
Class> c2 = Student.class
3、对象.getClass()
Class> c3 = new Student().getClass()

Class的使用

对象实例化正常操作使用new关键字实例化,但如果实例化好了Class对象,也可以用Class对象来进行具体类的实例化
示例代码:
Person p = (Person)c.newInstance()
这其实是调用的是Person的无参构造方法。
如果要调用有参构造方法实例化,则需要用到Constructor。 比较复杂,如果要使用Class实例化对象,最好保证类中存在一个无参构造方法

反射的应用

取得类的结构

一、取得类所实现的全部接口
public Class>[] getInterfaces()

二、取得类所实现的父类
Class> c2 = c1.getSuperclass()

三、取得类的构造方法
Constructor> con[] = c1.getConstructors()
取得修饰符:public int getModifiers()
取得方法名称:public String getName()
取得全部参数的类型:public Class>[] getParameterTypes()
还原修饰符 Modifier.toString(con[i].getModifiers())

四、取得全部方法
Method[] methods = c1.getDeclareMethods()
public Method[] getDeclareMethods() : 输出的是本类的全部方法
public Method[] getMethods() :输出全部方法,包括父类
取得返回值类型:Class> r = methods[i].getReturnType()
取得全部异常类型 Class>[] ex = methods[i].getExceptionTypes()

五、取得全部属性
public Field[] getDeclaredFields():输出本类中的全部属性,不包括父类和接口的
public Field[] getFields():得到实现的接口或父类中的公共属性,不包括本类的
取得属性类型:Class> r = f[i].getType(),进一步r.getName()

在一般开发工具中经常看见随笔提示功能,实际上此功能就是利用以上程序完成的

深入应用

1、通过反射调用类中的方法

如果想调用的话,则肯定必须清楚的知道要调用的方法名称是什么,之后通过Class类中的
public Method getMethod(String name,Class>… parameterTypes)

执行调用的方法:

public Object invoke(Object obj,Object... args)  
如method.invoke(activity,bindGet.param());

在如method.invoke(c1.newInstance())
调用无参方法:
Method met = c1.getMethod(“say”);
met.invoke(c1.newInstance())
调用有参方法:
Method met = c1.getMethod(“sayHello”,String.class,int.class)
met.invoke(c1.newInstance(),”小明”,30)

通过反射调用类setter及getter

setter及getter方法是一个标准的属性的访问方法,实际上此方法的操作之所以要这样规定,主要原因是由于反射机制可以给予支持
方法中属性首字母大写化
原理示例代码
public static void setter(Object obj,String att,Object value,Class> type){
Method met = obj.getClass().getMethod(“set”+initStr(att),type)
met.invoke(obj,value)
}
initStr(att)设首字母大写

2、通过反射调用属性

要操作一个类中的属性,可以通过Filed来完成
public Field getDeclareField(String name)
示例代码:
Class> c1 = Class.forName(“org.demo.Person”)
Object obj = c1.newInstance()
Field nameField = c1.getDeclareField(“name”)
nameField.setAccessible(true)
nameField.set(obj,”小明”)
注:该操作与setter和getter无关

3、通过反射操作数组

public Class> getComponentType()
示例代码:
int temp[] = {1,2,3}
Class> c = temp.getClass().getComponentType()
相关操作
取得第一位内容:Array.get(temp,0)

开辟新数组以及修改数组的大小
public static Object newInstance(Class> componentType,int… dimensions)
示例代码:
public static Object arrayInc(Object obj,int len){
Class> c = obj.getClass();
Class> arr = c.getComponentType();
Object newO = Array.newInstance(arr,len); //根据已知数组类型新建数组,长度为len
System.arraycopy(obj,0,newO,0,co)
}