掌握ReflectionUtils:解鎖Java反射的無限可能
作者:一安
在Spring框架中,ReflectionUtils是org.springframework.util包下的一個實用工具類,旨在簡化與反射相關的常見任務。它提供了一組方法,使得開發人員能夠更方便地執行反射操作,而不必處理過多的樣板代碼。
前言
反射是一種能夠在運行時檢查或操作程序結構、元數據和行為的特性。這使得程序能夠動態地獲取關于類、方法、字段等元素的信息,以及在運行時進行相應的操作。
獲取class對象的三種實現
- Class<? extends Demo> clazz = demo.getClass();
- Class<Demo> clazz = Demo.class;
- Class clazz = Class.forName("com.demo.Demo");
而在Spring框架中,ReflectionUtils是org.springframework.util包下的一個實用工具類,旨在簡化與反射相關的常見任務。它提供了一組方法,使得開發人員能夠更方便地執行反射操作,而不必處理過多的樣板代碼。
演示
獲取屬性字段
/**
* 獲取屬性字段
* 可以指定屬性的類型:findField(Class<?> clazz, @Nullable String name, @Nullable Class<?> type)
**/
public static void findField(){
//查找屬性字段name
Field name = ReflectionUtils.findField(Demo.class, "name");
System.out.println(name);
}
獲取對象的 field 屬性值
/**
* 獲取對象的 field 屬性值
**/
public static void getField() {
Demo demo = new Demo();
demo.setName("一安未來");
demo.setAge(20);
//獲取Demo中的name屬性字段
Field field = ReflectionUtils.findField(Demo.class, "name");
//取消name屬性的private權限控制
ReflectionUtils.makeAccessible(field);
//獲取對象的姓名字段的值
Object value = ReflectionUtils.getField(field, demo);
System.out.println(value);
}
設置對象的 field 屬性值
/**
* 設置對象的 field 屬性值
**/
public static void setField() {
Demo demo = new Demo();
demo.setName("一安未來");
demo.setAge(20);
//獲取Demo中的name屬性字段
Field field = ReflectionUtils.findField(Demo.class, "name");
//取消name屬性的private權限控制
ReflectionUtils.makeAccessible(field);
//設置對象的姓名字段的值
ReflectionUtils.setField(field, demo, "一安未來_v2");
System.out.println(demo.getName());
}
對象的值復制
/**
* 對象的值復制
**/
public static void shallowCopyFieldState() {
Demo demo = new Demo();
demo.setName("一安未來");
demo.setAge(20);
Demo demo1 = new Demo();
//把對象demo的值復制到對象demo1上
ReflectionUtils.shallowCopyFieldState(demo, demo1);
System.out.println(demo1);
}
對給定類的所有方法執行一個操作
/**
* 對給定類的所有方法執行一個操作
**/
public static void doWithMethods(){
ReflectionUtils.doWithMethods(Demo.class, method -> {
// 處理每個方法
System.out.println("找到方法:" + method.getName());
});
}
對給定類的所有字段執行一個操作
/**
* 對給定類的所有字段執行一個操作
**/
public static void doWithFields(){
ReflectionUtils.doWithFields(Demo.class, field -> {
// 處理每個字段
System.out.println("找到字段:" + field.getName());
});
}
添加過濾器來選擇性的處理方法或字段
/**
* 添加過濾器來選擇性地處理方法或字段
**/
public static void doWithMethodsFilter(){
ReflectionUtils.doWithMethods(
Demo.class,
method -> {
// 處理符合條件的方法
System.out.println("找到方法:" + method.getName());
},
method -> {
// 過濾器:選擇性處理方法的條件
return method.getName().startsWith("get");
}
);
}
調用指定方法
/**
* 調用指定方法
**/
public static void invokeMethod() throws NoSuchMethodException {
Demo demo = new Demo();
// 獲取方法對象
Method method =demo.getClass().getDeclaredMethod("say", String.class);
// 要傳遞的參數
String [] methodArgs = { "一安未來" };
ReflectionUtils.makeAccessible(method);
ReflectionUtils.invokeMethod(method, demo, methodArgs);
}
測試
public static void main(String[] args) throws NoSuchMethodException {
findField();
System.out.println("===============================");
getField();
System.out.println("===============================");
setField();
System.out.println("===============================");
shallowCopyFieldState();
System.out.println("===============================");
doWithMethods();
System.out.println("===============================");
doWithFields();
System.out.println("===============================");
doWithMethodsFilter();
System.out.println("===============================");
invokeMethod();
}
輸出:
private java.lang.String org.yian.reflectionUtils.Demo.name
===============================
一安未來
===============================
一安未來_v2
===============================
Demo(name=一安未來, age=20)
===============================
找到方法:equals
找到方法:toString
找到方法:hashCode
找到方法:getName
找到方法:setName
找到方法:say
找到方法:getAge
找到方法:setAge
找到方法:canEqual
找到方法:finalize
找到方法:wait
找到方法:wait
找到方法:wait
找到方法:equals
找到方法:toString
找到方法:hashCode
找到方法:getClass
找到方法:clone
找到方法:notify
找到方法:notifyAll
找到方法:registerNatives
===============================
找到字段:name
找到字段:age
===============================
找到方法:getName
找到方法:getAge
找到方法:getClass
===============================
I'm 一安未來
責任編輯:武曉燕
來源:
一安未來