反射是 Java 的動態特性核心:在執行期動態獲取類別結構、建立實例、呼叫方法、存取屬性,即使編譯期完全未知該類別。這使 Java 擁有類似動態語言的靈活性,廣泛應用於框架開發(Spring、Hibernate)、註解處理、序列化庫等。
java.lang.Class:反射入口,代表執行期類別物件java.lang.reflect.Constructor:建構子資訊與實例化java.lang.reflect.Field:欄位資訊與存取java.lang.reflect.Method:方法資訊與呼叫java.lang.reflect.Modifier:修飾符解析工具// 1. 類別字面常數(編譯期已知)
Class<?> c1 = UserBean.class;
// 2. 實例.getClass()(執行期已有實例)
UserBean user = new UserBean();
Class<?> c2 = user.getClass();
// 3. Class.forName()(完全動態,字串指定類別名)
Class<?> c3 = Class.forName("com.alfred.bean.UserBean");
setAccessible(true) 可存取 private 成員package com.alfred.main;
import java.lang.reflect.*;
public class Reflection {
// 列印完整類別結構(含繼承、介面、屬性、建構子、方法)
public static void printClassStructure(Class<?> c) { /* 實作略 */ }
// 獲取物件屬性值
public static Object getProperty(Object owner, String fieldName) throws Exception {
Field field = owner.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(owner);
}
// 獲取靜態屬性值
public static Object getStaticProperty(String className, String fieldName) throws Exception {
Field field = Class.forName(className).getField(fieldName);
return field.get(null);
}
// 呼叫實例方法
public static Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
Class<?>[] argTypes = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) argTypes[i] = args[i].getClass();
Method method = owner.getClass().getMethod(methodName, argTypes);
return method.invoke(owner, args);
}
// 呼叫靜態方法
public static Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception { /* 類似實例方法 */ }
// 動態建立實例
public static Object newInstance(String className, Object[] args) throws Exception { /* 略 */ }
// 陣列操作
public static Object getByArray(Object array, int index) {
return Array.get(array, index);
}
}
| 面向 | 影響 | 優化建議 |
|---|---|---|
| 效能 | 反射比直接呼叫慢 10-100 倍 | 緩存 Class/Method/Field 物件;使用 MethodHandle (JDK 7+) |
| 安全 | 可繞過封裝存取 private 成員 | SecurityManager 限制;模組化系統 (JPMS) 封裝模組內部 |
| 維護 | 編譯期無法檢查,重構風險高 | 儘量用介面/抽象類別隔離;配合註解驗證 |
反射是 Java 動態性的基石,賦予框架級開發核心能力。掌握 Class、Method、Field、Constructor 四大核心 API,理解 setAccessible(true) 突破封裝機制,能深度理解主流框架原理並開發通用工具。實際專案中需權衡靈活性與效能、安全性,善用緩存與新式 API(MethodHandle、VarHandle)提升效能。