首先需要获取类型类,一般获取类型类有三种方式
- 从类名获得:MyClass.class即可,适用于知道类名
- 从对象获得:myClass.getClass(),适用于有对象句柄
- 偷来的:Class.forName(“com.crimson.MyClass”)需要类名和包名,不常用
这里选了第一种,假设获取的对象为a。
然后是获取该类型的构造器,方法和字段。
全都依靠以get开头的各种方法。
根据返回对象不同有constructor、field、method三种,意思是构造器、字段和方法。根据访问权限不同有公开的和公开+私有,加上Declared获取的就是公开+私有。
如getDeclaredMethods获取所有方法、getMethods仅获取公开方法,getFields仅获取公开的字段。返回对象的用对应的数组装起来就可以了,在代码里第一段里有演示。如Method methods[]=a.getDeclaredMethods()。
private的可以访问前,先setAccessible(true),把访问权限强制打开,访问完记得再关闭就可以了。
获取指定名字的字段方法和构造器,字段和方法把名字作为参数,如getDeclaredMethod(“setId”),注意结尾是method没有s,因为只获取单个方法,也不需要用数组装了。直接Method m=getMethod(“myMethod”)。
对于获取指定的构造器,get方法里面填想获取构造器的参数的class,无参的就不填。
如果你想获取MyClass(int,int)的构造器,就getDeclaredConstructor(int.class,int.class)就可以了
同样的,获取的是单个构造器,注意结尾没有s。
对于已经获取到的构造器例如c,可以使用它的newInstance方法获取它制造的新对象,如c.newInstance(100,200)
对于已经获取到的字段对象,可以读取出来,使用get(对象)或者getInt()之类用于基本数据类型,还可以用set(对象,值)设值。
对于已经获取的方法,可以用invoke(对象,参数)调用该方法。具体流程参见下面代码。
代码如下
package com.crimson.master;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** 分析反射 */