正常方式:引入需要的“包.类”名称 ---> 通过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)
}
网友评论