詳細示範如何使用 Java 反射 API 動態載入並實例化內部類,涵蓋 public static、package-private、non-static 內部類的建構子參數差異處理。
package javalang;
public class Outer {
public static class Inner1 {}
}
Class.forName("javalang.Outer$Inner1") // 輸出: class javalang.Outer$Inner1
// public static 內部類
Class.forName("javalang.Outer$Inner1").getConstructors().length // 1
Class.forName("javalang.Outer$Inner1").getConstructors()[0] // public javalang.Outer$Inner1()
// 移除 public 修飾字後
.getConstructors().length // 0 (僅回傳 public 建構子)
.getDeclaredConstructors().length // 1 (包含非 public)
.getDeclaredConstructors()[0] // javalang.Outer$Inner1()
// public static 內部類
Class.forName("javalang.Outer$Inner1")
.getConstructors()[0].newInstance(); // 成功
// 非 public 內部類
Class.forName("javalang.Outer$Inner1")
.getDeclaredConstructors()[0].newInstance(); // 成功 (需 setAccessible(true) 或同包)
移除 static 後,建構子簽名變為:
javalang.Outer$Inner1(javalang.Outer)
必須傳入外部類實例:
Class.forName("javalang.Outer$Inner1")
.getDeclaredConstructors()[0].newInstance(new Outer()); // 成功
getConstructors() 僅回傳 public 建構子;getDeclaredConstructors() 回傳所有宣告建構子。IllegalArgumentException: wrong number of arguments。