反射機制允許程序在運行時檢查類、接口、字段、方法的結構,並動態創建對象、調用方法、訪問字段。它是框架(Spring、Hibernate、MyBatis)、注解處理、序列化庫的基石。
Class<T>:類的運行時表示,反射入口。Field:成員變量。Method:方法。Constructor<T>:構造器。Modifier:修飾符解析工具。Class> c1 = String.class; // 1. 類字面量
Class> c2 = "hello".getClass(); // 2. 實例 getClass()
Class> c3 = Class.forName("java.lang.String"); // 3. 完整類名(可能拋 ClassNotFoundException)
public Object getFieldValue(Object obj, String fieldName) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName); // 獲取聲明字段(含私有)
field.setAccessible(true); // 取消訪問檢查
return field.get(obj);
}
public void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public Object invokeMethod(Object obj, String methodName, Object... args) throws Exception {
Class>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class>[]::new);
Method method = obj.getClass().getDeclaredMethod(methodName, argTypes);
method.setAccessible(true);
return method.invoke(obj, args); // 核心:Method.invoke(實例, 參數陣列)
}
// 調用靜態方法
public Object invokeStaticMethod(String className, String methodName, Object... args) throws Exception {
Class> clazz = Class.forName(className);
Class>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class>[]::new);
Method method = clazz.getDeclaredMethod(methodName, argTypes);
method.setAccessible(true);
return method.invoke(null, args); // 靜態方法實例傳 null
}
public Object newInstance(String className, Object... args) throws Exception {
Class> clazz = Class.forName(className);
Class>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class>[]::new);
Constructor> cons = clazz.getDeclaredConstructor(argTypes);
cons.setAccessible(true);
return cons.newInstance(args);
}
// 無參構造器簡化
Object obj = Class.forName("com.example.User").getDeclaredConstructor().newInstance();
// instanceof 等價
boolean isStr = String.class.isInstance("hello"); // true
// 數組獲取/設置
int[] arr = {1,2,3};
Array.get(arr, 1); // 2
Array.set(arr, 1, 99);
invoke 拋出 InvocationTargetException,真實業務異常包裹在 getCause() 中。MethodHandle 或緩存 Method 對象優化。setAccessible(true) 可能被 SecurityManager 禁止。依賴注入(IOC)、AOP 代理、ORM 映射、注解驅動開發、插件系統、動態腳本、測試框架等。