反射可破壞封裝,在運行期動態讀寫私有欄位、呼叫方法,是框架 (Spring/Hibernate/Jackson) 核心機制。本文通過 UserBean 實例演示完整流程。
public class UserBean {
private Integer id;
private int age;
private String name;
private String address;
// getter/setter 省略
}
UserBean bean = new UserBean();
bean.setId(100);
bean.setAddress("武漢");
Class> clazz = bean.getClass();
// 1. 獲取所有宣告欄位 (含私有)
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true); // 關鍵:暴力反射
Object val = f.get(bean);
System.out.println("欄位: " + f.getName() + " = " + val);
// 2. 根據型別動態設值
Class> type = f.getType();
if (type == String.class) f.set(bean, "反射修改");
else if (type == int.class || type == Integer.class) f.set(bean, 999);
}
// 3. 獲取 getter 方法並調用
for (Method m : clazz.getMethods()) {
if (m.getName().startsWith("get")) {
System.out.println(m.getName() + " = " + m.invoke(bean));
}
}
getDeclaredFields() 取得**本類宣告**欄位 (含 private);getFields() 僅取 public (含繼承)。f.setAccessible(true) 關閉存取檢查,**生產碼慎用**,框架內部常見。f.getType() 回傳 int.class 等;包裝型別回傳 Integer.class。Method.invoke(obj, args) 需傳遞實例 (靜態方法傳 null)。IllegalAccessException、InvocationTargetException (底層真實異常在 getCause())。toString()、equals()、序列化工具類實作。@Value("${key}") 解析)。