首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 反射修改私有字段與調用私有方法:Field.setAccessible 實戰詳解

     編輯:Java 相關知識

核心步驟三部曲

  1. 獲取 Field/Method:getDeclaredField / getDeclaredMethod
  2. 暴力開啟訪問:setAccessible(true)
  3. 讀寫/調用:field.set(obj, value) / method.invoke(obj, args)

完整代碼示例

import java.lang.reflect.*;

public class ReflectionModifier {
    public static void main(String[] args) throws Exception {
        // 目標對象
        DemoTest target = new DemoTest();
        Class clazz = target.getClass();

        // --- 1. 修改私有字段 ---
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true);              // 關鍵!
        nameField.set(target, "王五");               // 修改值
        System.out.println("修改後 name = " + nameField.get(target)); // 驗證

        // --- 2. 調用私有方法 ---
        Method privateMethod = clazz.getDeclaredMethod("getName2");
        privateMethod.setAccessible(true);
        String result = (String) privateMethod.invoke(target);
        System.out.println("私有方法返回: " + result);
    }
}

class DemoTest {
    private String name = "123";

    public String getName() {
        System.out.println("public getName: " + name);
        return name;
    }

    private String getName2() {
        System.out.println("private getName2: " + name);
        return name;
    }
}

關鍵 API 速查表

操作API說明
獲取所有聲明字段getDeclaredFields()含 private/protected/default/public,不含繼承
獲取 public 字段getFields()含繼承鏈 public 字段
獲取聲明方法getDeclaredMethod(name, paramTypes)精確匹配參數類型
修改字段值field.set(obj, newValue)基本類型自動拆箱/裝箱
讀取字段值field.get(obj)返回 Object,需轉型

實戰場景與注意事項

  • 單元測試 Mock:注入私有依賴、驗證內部狀態。
  • 框架開發:Spring 注入 @Autowired 私有字段、Hibernate 設置實體 ID。
  • 性能警示:反射比直接調用慢 10-100 倍,熱點路徑請緩存 Field/Method 對象。
  • 安全風險:破壞封裝可能導致不變量被破壞,生產代碼慎用;模塊化系統 (JPMS) 可能拒絕深度反射。

掌握 setAccessible(true) 這把「萬能鑰匙」,同時牢記「大權在手,責任在肩」。業務邏輯請優先通過公共 API 完成,反射留給基礎設施層。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved