如何通過反射構造內部類物件
阿新 • • 發佈:2018-12-26
嘛。所以我們可以這樣寫:
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,原來如此。看來非靜態的內部類沒有預設的構造方法,構造時需要傳一個外部類的例項作為引數。
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
}
輸出結果: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,原來如此。看來非靜態的內部類沒有預設的構造方法,構造時需要傳一個外部類的例項作為引數。