反射是这样被定义的:在运行状态中,能够获取任意一个类或者对象的属性或者调用他们的方法
那么首先要了解的就是获取类或者对象的方式
第一种:new方式 , Class1 c1=new Class1();这里的c1就是这个类的对象;c1.getClass()获取类
第二种:.class方式, Class c1= Class1.clsss ;这里的c1是个类,通过newInstance创建它的对象
第三种:forName方式 Class c1=Class.forName(“test.Class1”)括号里为类完整路径,这里的c1也是个类,通过newInstance创建它的对象
现在知道了怎么去获取某个类或者该类的对象,接下来说一说反射
我第一次接触到反射是从获取类属性开始的,(具体场景是给某个类添加toMap的方法,就是把类属性转为map)下面看一个例子
我创建了一个类test1,给他添加了属性和get,set方法
public class test1{
private Integer id;
private String name;
private String pass;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
接下来为它添加toMap的方法
public Map<String, Object> toMap() {
Map<String, Object> mapres = new HashMap<String, Object>(1);
Class<?> class1 = this.getClass();
Field[] fields = class1.getDeclaredFields();
for (Field field : fields) {
try {
Method method = class1.getDeclaredMethod("get"
+ StringUtils.capitalise(field.getName()));
Object object = method.invoke(this);
mapres.put(field.getName(), object);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return mapres;
}
我们来看一看这个方法,首先,this这个类的实例,用getClass获取到这个类,然后用getDeclaredFields获得声明的属性,然后遍历属性依次获得获取该属性值得方法,再将键值放入到map里,这个例子就很好地诠释了反射的定义。
然后我们可以测试一下
public static void main(String[] args) {
test1 t1 = new test1();
t1.setId(5);
t1.setName("aaa");
t1.setPass("bbb");
log.info(t1.toMap());
}
输出结果 {id=5, pass=bbb, name=aaa}
其实通过获取到的Class对象我们可以得到很多东西,获取属性,构造器,方法,注解等等,如图
接下来要说的是获取到的方法和方法的反射
通过类获取声明的方法有getDeclaredMethod获取单个方法,getDeclaredMethods获取多个方法。getDeclaredMethod()参数必须有方法名,然后后续接的是该方法对应的输入参数类型的class对象。
举个例子,
假如类test1里有个方法a()
public String a(){
…
}
调用方式
Method m1= test1.class.getMethod("a");
Object object=m1.invoke(test1.class.newInstance());
当然,你也可以写成这样,
Method m1= test1.class.getMethod("a",null);
Object object=m1.invoke(test1.class.newInstance(),null);
反正null值在传入后也会被处理掉
假如类test1里有个方法b()
public String a(String aa,Integer bb,Object cc){
…
}
调用方式
Method m1= test1.class.getMethod("b",String.class,Integer.class.Object.class);
Object object=m1.invoke(test1.class.newInstance(),”abc”,1,3);
为什么方法名写在第一位,参数类型类class对象写在后面,因为源码是这样的
public Object invoke(Object obj, Object... args)
很多人都说,java的反射机制被很多优秀的框架所使用,我第一个就想到了spring框架,
待补