反射被喻為「小偷的萬能鑰匙」,能繞過編譯期訪問檢查,在運行時動態獲取類信息、創建實例、訪問私有成員、調用任意方法。本文深度剖析反射核心 API、破壞封裝原理、安全風險、效能代價與生產環境約束準則。
package person.lb.reflect;
public class House {
private String owner = "nobounds"; // 私有字段
private int roomNum = 3;
public String dustbin = "垃圾桶"; // 公有字段
private void turnOnTV() { // 私有方法
System.out.println("打開電視...");
}
public String getOwner() { return owner; }
}
package person.lb.reflect;
import java.lang.reflect.*;
public class KeyDemo {
public static void main(String[] args) throws Exception {
// 1. 獲取 Class 對象
Class> clazz = Class.forName("person.lb.reflect.House");
System.out.println("戶主類: " + clazz.getName());
// 2. 掃描所有字段(含私有)
Field[] fields = clazz.getDeclaredFields();
System.out.println("=== 掃描字段 ===");
for (Field f : fields) {
System.out.printf("類型:%s 名稱:%s 權限:%s%n",
f.getType().getSimpleName(), f.getName(), Modifier.toString(f.getModifiers()));
}
// 3. 掃描所有方法(含私有)
Method[] methods = clazz.getDeclaredMethods();
System.out.println("=== 掃描方法 ===");
for (Method m : methods) {
System.out.printf("方法:%s 參數:%s 返回:%s%n",
m.getName(), Arrays.toString(m.getParameterTypes()), m.getReturnType().getSimpleName());
}
// 4. 實例化並暴力訪問私有字段
House house = (House) clazz.getDeclaredConstructor().newInstance();
Field ownerField = clazz.getDeclaredField("owner");
ownerField.setAccessible(true); // 關鍵:暴力反射開關
System.out.println("原擁有者: " + ownerField.get(house)); // nobounds
ownerField.set(house, "thief"); // 竊取所有權
System.out.println("新擁有者: " + house.getOwner()); // thief
// 5. 調用私有方法
Method tvMethod = clazz.getDeclaredMethod("turnOnTV");
tvMethod.setAccessible(true);
tvMethod.invoke(house); // 輸出: 打開電視...
}
}
戶主類: person.lb.reflect.House
=== 掃描字段 ===
類型:String 名稱:owner 權限:private
類型:int 名稱:roomNum 權限:private
類型:String 名稱:dustbin 權限:public
=== 掃描方法 ===
方法:getOwner 參數:[] 返回:String
方法:turnOnTV 參數:[] 返回:void
原擁有者: nobounds
新擁有者: thief
打開電視...
setAccessible(true) 關閉 JVM 訪問檢查(AccessController.doPrivileged 特權動作)Unsafe.putObject 底層實現)final 字段(除非被 JIT 常量折疊)| 維度 | 影響 | 數量級 |
|---|---|---|
| 效能 | 方法調用比直接調用慢 10-100 倍(無法內聯、參數裝箱、訪問檢查) | 微秒級 vs 納秒級 |
| 安全 | 破壞封裝邊界,洩露內部實現,惡意代碼可竊取/篡改敏感數據 | 安全審計重點 |
| 維護 | 字符串引用類名/方法名,重構不報錯,運行時才炸 | 脆弱性極高 |