一、ReflectionUtils
在 Java
中,反射(Reflection
)是一种强大的机制,允许程序在运行时动态地检查类、获取类的信息、调用类的方法、访问或修改类的属性等。Java
的反射机制提供了一组类和接口,位于 java.lang.reflect
包中,通过反射可以动态加载类、动态获取类的信息、动态创建对象、动态调用方法、动态访问和修改属性等。
在 Spring Framework
中也有一个也反射相关的工具类,那就是 ReflectionUtils
,它位于 org.springframework.util
包中,简化 Java
反射操作,提供了以下几个功能:
-
遍历类的属性和方法:提供了静态方法
doWithFields()
和doWithMethods()
,允许你遍历一个类的所有属性和方法,并且可以对每个属性和方法执行自定义的操作。 -
查找指定名称的属性和方法:提供了方法
findField()
和findMethod()
,用于查找类中指定名称的属性和方法。 -
执行方法:提供了方法
invokeMethod()
,可以用于执行类中的方法。 -
获取和设置属性值:提供了方法
getField()
和setField()
,可以用于获取和设置类的属性值。 -
复制属性值:提供了方法
shallowCopyFieldState()
,可以用于将源对象的属性值复制到目标对象中。
1. 获取类的属性
public class Test1 {
private String name;
private String sex;
private int age;
public static void main(String[] args) {
ReflectionUtils.doWithFields(Test1.class, field -> {
System.out.println("field name: " + field.getName());
System.out.println("field type: " + field.getType());
});
}
}
2. 获取属性的内容
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Test2 {
private String name;
private String sex;
private int age;
public static void main(String[] args) {
Test2 target = new Test2("张三", "男", 21);
ReflectionUtils.doWithFields(target.getClass(), fieldName ->
Optional.ofNullable(ReflectionUtils.findField(target.getClass(), fieldName.getName())).ifPresent(field -> {
ReflectionUtils.makeAccessible(field);
Object value = ReflectionUtils.getField(field, target);
System.out.println("fileName: " + fieldName.getName() + " , value: " + value);
})
);
}
}
3. 动态修改属性的值
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Test2 {
private String name;
private String sex;
private int age;
public static void main(String[] args) {
Test2 target = new Test2("张三", "男", 21);
Field field = ReflectionUtils.findField(target.getClass(), "sex");
assert field == null;
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field,target,"女");
System.out.println(target.toString());
}
}
4. 动态执行方法
public class Test3 {
public void t1() {
System.out.println("this is t1 method ! ");
}
public String t2(String param) {
return "this is t2 method ! param: " + param;
}
public static void main(String[] args) {
Test3 target = new Test3();
Method t1 = ReflectionUtils.findMethod(target.getClass(), "t1");
assert t1 != null;
ReflectionUtils.invokeMethod(t1, target);
Method t2 = ReflectionUtils.findMethod(target.getClass(), "t2", String.class);
assert t2 != null;
String res = (String) ReflectionUtils.invokeMethod(t2, target, "测试");
System.out.println(res);
}
}