使用反射調用帶可變參數的構造器:
// 目標構造器
public Example01(String... args) { ... }
// 嘗試調用
constructor.newInstance("100", "200", "300"); // 拋出異常
// 必須寫成
constructor.newInstance(new Object[]{new String[]{"100", "200", "300"}}); // 正常
method(String... args) 編譯後等價於 method(String[] args)。newInstance(Object... initargs) 等價於 newInstance(Object[] initargs)。String[] 參數,則必須傳入一個Object[],其唯一元素為 String[]。
| 調用寫法 | 實際傳遞給 newInstance 的參數結構 | 匹配的構造器簽名 |
|---|---|---|
newInstance("100", "200", "300") | new Object[]{"100", "200", "300"} | Example01(String, String, String) 三個 String 參數 |
newInstance(new Object[]{"100", "200", "300"}) | new Object[]{new String[]{"100", "200", "300"}} | Example01(String[]) 一個 String 數組參數 |
newInstance(new Object[]{new String[]{"100", "200", "300"}}) | new Object[]{new String[]{"100", "200", "300"}} | Example01(String[]) 正確匹配 |
可變參數語法糖僅在編譯期直接調用方法時生效。反射調用屬於運行時動態調用,JVM 只看到 Object[] 參數數組,無法感知原始方法聲明為可變參數,因此無法自動將多個參數「打包」為一個數組參數。
// 獲取構造器
Constructor> constructor = Example01.class.getConstructor(String[].class);
// 正確調用:構造參數數組
Object[] args = new Object[]{new String[]{"100", "200", "300"}};
Example01 instance = (Example01) constructor.newInstance(args);
反射調用可變參數構造器/方法時,必須手動將實參包裝為與形參列表完全一致的 Object[]。理解「可變參數 = 數組」及「反射參數 = Object[]」的雙重數組結構,是避免此類錯誤的關鍵。