程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 通過反射構造內部類對象

通過反射構造內部類對象

編輯:關於JAVA

首先在 javalang 包下寫一個包含內部類的類:

package javalang;

public class Outer {
    public static class Inner1{}
}

注意這個類是 public static,後面我們慢慢把這些修飾符去掉。

要想通過反射來創建 Inner1 對象,首先要獲得 Inner1 的 Class 對象。我們在 Outer 中寫上 main 方法:

public class Outer {
    public static class Inner1{}
   
    public static void main(String[] args) {
        System.out.println(Inner1.class);
    }
}

輸出結果:class javalang.Outer$Inner1

然後我們試一下這個類名對不對:

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

運行一下,沒錯。然後就是用它來創建對象。創建對象要靠構造方法。這個類有沒有 構造方法呢?我們可以這麼寫:

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

運行一下,輸出 1。看來有。然後看看這個構造方法是什麼樣子的:

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

輸出結果:public javalang.Outer$Inner1()。這就是缺省構造方法嘛。所以我們可 以這樣寫:

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

輸出結果:javalang.Outer$Inner1@ca0b6。這說明執行成功了。

接下來我們把 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());
}

輸出結果:javalang.Outer$Inner1@ca0b6。現在我們可以用反射來構造非公開內部類 的對象了。

接下來,我們再把 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 ()));
}

輸出結果:javalang.Outer$Inner1@ca0b6

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved