1. 程式人生 > >如何通過反射構造內部類物件

如何通過反射構造內部類物件

嘛。所以我們可以這樣寫:

public static void main(String[] args) throws Exception {
    System.out.println(Class.forName("javalang.Outer$Inner1")
            .getConstructors()[0].newInstance();
}


輸出結果:[email protected]。這說明執行成功了。

接下來我們把 Inner 的 public 關鍵字去掉,然後再執行。結果報錯了:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0


這說明沒有找到構造方法。真的沒有嗎?我們把 main 方法改回來:

public static void main(String[] args) throws Exception {
    System.out.println(Class.forName("javalang.Outer$Inner1")
            .getConstructors().length);
}


輸出結果:0。真的沒有構造方法嗎?其實不是,只是構造方法不是公開的。這時我們必須用 getDeclaredConstructors() 來獲得:

public static void main(String[] args) throws Exception {
    System.out.println(Class.forName("javalang.Outer$Inner1")
            .getDeclaredConstructors
().length);
}


輸出結果:1。這就把構造方法找到了。然後我們繼續呼叫這個構造方法:

public static void main(String[] args) throws Exception {
    System.out.println(Class.forName("javalang.Outer$Inner1")
            .getDeclaredConstructors()[0].newInstance());
}


輸出結果:[email protected]。現在我們可以用反射來構造非公開內部類的物件了。

接下來,我們再把 static 關鍵字去掉。這時候報錯了:
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments


這說明什麼呢?我們呼叫的時候沒有傳引數,而錯誤內容就是說引數數量不正確。那麼這個構造方法有什麼引數呢?我們改一下程式碼看看:

public static void main(String[] args) throws Exception {
    System.out.println(Class.forName("javalang.Outer$Inner1")
            .getDeclaredConstructors()[0]);
}


輸出結果:javalang.Outer$Inner1(javalang.Outer)

原來構造方法裡面需要一個 Outer 型別的引數。這好辦:

public static void main(String[] args) throws Exception {
    System.out.println(Class.forName("javalang.Outer$Inner1")
            .getDeclaredConstructors()[0].newInstance(new Outer()));
}


輸出結果:[email protected]

OK,原來如此。看來非靜態的內部類沒有預設的構造方法,構造時需要傳一個外部類的例項作為引數。