反射 是 Java 語言的核心特性之一,允許執行中的程式檢視自身結構、動態獲取類別資訊(方法、欄位、建構子等)並進行操作。這在 C/C++ 等靜態語言中幾乎無法實現,是 Java 動態性的基石,廣泛應用於框架開發、序列化、依賴注入等場景。
Class.forName("全限定類名")、類別名.class、實例.getClass()getDeclaredMethods()、getDeclaredFields()、getDeclaredConstructors()Method.invoke()、Field.set()、Constructor.newInstance()Class<?> cls = Class.forName("java.util.Stack");
Method[] methods = cls.getDeclaredMethods();
for (Method m : methods) {
System.out.println(m.toString()); // 含修飾詞、回傳型別、參數列表
}
Class<?> cls = Class.forName("A");
System.out.println(cls.isInstance(new Integer(37))); // false
System.out.println(cls.isInstance(new A())); // true
Class<?> cls = Class.forName("MethodDemo");
Method add = cls.getMethod("add", int.class, int.class);
Object result = add.invoke(cls.getDeclaredConstructor().newInstance(), 37, 47);
System.out.println(result); // 84
// 建構子帶參實例化
Constructor<?> ctor = cls.getConstructor(int.class, double.class);
Object obj = ctor.newInstance(10, 3.14);
// 修改 private 欄位
Field field = cls.getDeclaredField("secret");
field.setAccessible(true);
field.set(obj, "new value");
// 建立 String[10]
Object arr = Array.newInstance(String.class, 10);
Array.set(arr, 5, "test");
String val = (String) Array.get(arr, 5);
// 多維陣列 int[5][10][15]
int[] dims = {5, 10, 15};
Object matrix = Array.newInstance(int.class, dims);
Array.setInt(Array.get(Array.get(matrix, 3), 5), 10, 37);
| 優勢 | 代價 |
|---|---|
| 極致動態性、框架級解耦 | 效能開銷(JIT 難優化)、破壞封裝、編譯期失去型別檢查 |
生產建議:核心熱路徑避免反射;框架啟動期掃描、註解處理、配置綁定等場景大膽使用。JDK 9+ 推薦改用 MethodHandles / VarHandles 獲得更好效能與模組化支援。