最近在学习Spring MVC里面不乏许多注解,注解类似@Data会破坏java的保护机制,不用get、set方法就能进行赋值,其中注解里面用到的就是反射机制
例如下面的例子
public @Data class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String userName;
private String userId;
反射机制:
package com.fandq.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectSample {
private String name;
private int level;
public String toString() {
return name+":"+level;
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
// 正规路子初始化对象
ReflectSample sample = new ReflectSample();
sample.level=10;
sample.name ="测试";
System.out.println(sample.toString());
//通过反射 打印class私有方法
Class clz = Class.forName("com.fandq.reflect.ReflectSample");
System.out.println("forName方法:"+clz);//forName方法:class com.fandq.reflect.ReflectSample
Method []ms = clz.getDeclaredMethods();
for(Method method:ms) {
if(method.getParameterTypes().length>0) {
//打印方法名称 和方法第一个参数类型
System.out.println(method.getName()+"|"+method.getParameterTypes()[0].getName());
//打印结果是:main|[Ljava.lang.String; setName|java.lang.String; setLevel|int
}else {
System.out.println(method.getName());
//打印不带参数的方法有:toString; getName; getLevel
}
}
//通过反射的newInstance方法实例化对象
Object object = clz.newInstance();
//getDeclared开头的方法只会获取class本身的,不会获取继承的
Method setName = clz.getDeclaredMethod("setName", String.class);
//setAccessible方法,绕过Java默认的访问控制检查,比如可以直接获取到对象的私有域的值或是调用私有方法
setName.setAccessible(true);
Method setLevel = clz.getDeclaredMethod("setLevel",int.class );
setName.invoke(object, "reflect");
setLevel.invoke(object, 20);
//System.out.println("反射对象执行:"+object.toString());
//反射 field赋值
Object object2 = clz.newInstance();
Field nameField = clz.getDeclaredField("name") ;
nameField.setAccessible(true);
nameField.set(object2, "field");
//上述语句 等价于 ReflectSample.name="field"
Field levelField = clz.getDeclaredField("level") ;
levelField.setAccessible(true);
levelField.set(object2, 20);
System.out.println("反射对象field赋值执行:"+object2.toString());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}