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

Java 反射機制深度解析:核心原理、Class API 與實戰範例

     編輯:Java 相關知識

一、什麼是 Java 反射?

Java 反射機制允許程式在運行時動態獲取類的完整結構資訊(構造器、欄位、方法、註解、繼承關係等),並能實例化物件、呼叫方法、存取欄位。簡單說:已知「類名」或「物件」,即可還原「類的全部定義」。

核心兩步驟

  1. 根據類全名獲取 Class 物件(Class.forName()、.class、obj.getClass())。
  2. 透過 Class 提供的 API 讀取構造器、方法、欄位等元資料並操作。

二、獲取 Class 物件的四種方式

// 1. 類全名字串(最常用,支援動態載入)
Class cls1 = Class.forName("com.example.Person");

// 2. 類字面常量(編譯期可檢查)
Class cls2 = Person.class;

// 3. 實例物件
Person p = new Person();
Class cls3 = p.getClass();

// 4. 字串物件(注意:這會得到 String.class,非目標類)
String className = "com.example.Person";
Class cls4 = className.getClass(); // 結果是 java.lang.String

三、Class 核心 API 分類速查

分類代表方法說明
構造器getConstructor(s)、getDeclaredConstructor(s)前者僅 public,後者含私有;可用 setAccessible(true) 破壞封裝
方法getMethod(s)、getDeclaredMethod(s)同構造器邏輯;invoke(obj, args) 執行呼叫
欄位getField(s)、getDeclaredField(s)前者含繼承 public,後者含私有;set(obj, value) 賦值
類元資料getSuperclass()、getInterfaces()、getAnnotations()繼承鏈、實現介面、運行時註解
判斷特性isInterface()、isEnum()、isPrimitive()、isAnonymousClass()快速識別類型特徵

四、實戰範例精華

1. 動態呼叫私有構造器與方法

Class cls = Class.forName("com.example.Person");
// 取私有無參構造器
Constructor cst = cls.getDeclaredConstructor();
cst.setAccessible(true);
Object obj = cst.newInstance();

// 取私有方法 setGender(Gender)
Method m = cls.getDeclaredMethod("setGender", Gender.class);
m.setAccessible(true);
m.invoke(obj, Gender.MALE);

2. 獲取泛型父類與介面實際類型參數

class UserDao extends BaseDao {}
// 運行時可解析出 User、Long
Type superType = UserDao.class.getGenericSuperclass();
ParameterizedType pType = (ParameterizedType) superType;
Type[] actualTypes = pType.getActualTypeArguments(); // [User, Long]

3. 註解掃描應用場景

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface ApiDoc { String value(); }

class Controller {
    @ApiDoc("用戶登入")
    public void login() {}
}

// 掃描
for (Method m : Controller.class.getDeclaredMethods()) {
    if (m.isAnnotationPresent(ApiDoc.class)) {
        System.out.println(m.getAnnotation(ApiDoc.class).value());
    }
}

五、效能與安全注意事項

  • 效能:反射比直接呼叫慢(JIT 難優化、存取檢查),熱點路徑避免頻繁使用;可用 MethodHandle 或緩存 Method/Field 物件緩解。
  • 安全:setAccessible(true) 可能被 SecurityManager 禁止;模組化(JPMS)下需 opens 導出封裝。
  • 泛型擦除:運行時無法直接獲取泛型實際類型,需透過 Type 系統(ParameterizedType、TypeVariable)配合繼承結構推導。

六、總結

反射是框架(Spring、Hibernate、Jackson、MyBatis 等)實現「約定優於配置」、「依賴注入」、「ORM 映射」的基石。掌握 Class、Constructor、Method、Field 四大核心類及其 Declared 與非 Declared 差異,配合 setAccessible 與泛型 Type 體系,即可駕馭動態編程的強大威力。

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