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

Java 反射機制與 Method.invoke 詳解

     編輯:Java 相關知識

Java 反射:運行時動態獲取類信息並操作對象

反射機制允許程序在運行時檢查類、接口、字段、方法的結構,並動態創建對象、調用方法、訪問字段。它是框架(Spring、Hibernate、MyBatis)、注解處理、序列化庫的基石。

核心類

  • Class<T>:類的運行時表示,反射入口。
  • Field:成員變量。
  • Method:方法。
  • Constructor<T>:構造器。
  • Modifier:修飾符解析工具。

常用操作代碼範例

1. 獲取 Class 對象的三種方式

Class c1 = String.class;           // 1. 類字面量
Class c2 = "hello".getClass();       // 2. 實例 getClass()
Class c3 = Class.forName("java.lang.String"); // 3. 完整類名(可能拋 ClassNotFoundException)

2. 訪問字段

public Object getFieldValue(Object obj, String fieldName) throws Exception {
    Field field = obj.getClass().getDeclaredField(fieldName); // 獲取聲明字段(含私有)
    field.setAccessible(true); // 取消訪問檢查
    return field.get(obj);
}

public void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
    Field field = obj.getClass().getDeclaredField(fieldName);
    field.setAccessible(true);
    field.set(obj, value);
}

3. 調用方法

public Object invokeMethod(Object obj, String methodName, Object... args) throws Exception {
    Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
    Method method = obj.getClass().getDeclaredMethod(methodName, argTypes);
    method.setAccessible(true);
    return method.invoke(obj, args); // 核心:Method.invoke(實例, 參數陣列)
}

// 調用靜態方法
public Object invokeStaticMethod(String className, String methodName, Object... args) throws Exception {
    Class clazz = Class.forName(className);
    Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
    Method method = clazz.getDeclaredMethod(methodName, argTypes);
    method.setAccessible(true);
    return method.invoke(null, args); // 靜態方法實例傳 null
}

4. 動態創建實例

public Object newInstance(String className, Object... args) throws Exception {
    Class clazz = Class.forName(className);
    Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
    Constructor cons = clazz.getDeclaredConstructor(argTypes);
    cons.setAccessible(true);
    return cons.newInstance(args);
}

// 無參構造器簡化
Object obj = Class.forName("com.example.User").getDeclaredConstructor().newInstance();

5. 判斷實例類型 & 數組操作

// instanceof 等價
boolean isStr = String.class.isInstance("hello"); // true

// 數組獲取/設置
int[] arr = {1,2,3};
Array.get(arr, 1); // 2
Array.set(arr, 1, 99);

Method.invoke 關鍵點

  • 參數匹配:實參類型必須與形參類型兼容(基本類型自動裝箱/拆箱)。可變參數方法需傳遞數組。
  • 異常處理:invoke 拋出 InvocationTargetException,真實業務異常包裹在 getCause() 中。
  • 性能:反射調用比直接調用慢(JIT 優化有限),熱點路徑可用 MethodHandle 或緩存 Method 對象優化。
  • 安全性:setAccessible(true) 可能被 SecurityManager 禁止。

應用場景

依賴注入(IOC)、AOP 代理、ORM 映射、注解驅動開發、插件系統、動態腳本、測試框架等。

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