2011-09-19 39 views
17

在Jonathan Skeet的final variable passed to anonymous class via constructor中提到變量通過自動生成的構造函數傳遞給匿名類實例。爲什麼我無法看到在這種情況下使用反射構造:將最終變量傳遞給匿名類

public static void main(String... args) throws InterruptedException { 
final int x = 100; 
new Thread() { 
    public void run() { 
     System.out.println(x);  
     for (Constructor<?> cons : this.getClass() 
       .getDeclaredConstructors()) { 
      StringBuilder str = new StringBuilder(); 
      str.append("constructor : ").append(cons.getName()) 
        .append("("); 
      for (Class<?> param : cons.getParameterTypes()) { 
       str.append(param.getSimpleName()).append(", "); 
      } 
      if (str.charAt(str.length() - 1) == ' ') { 
       str.replace(str.length() - 2, str.length(), ")"); 
      } else 
       str.append(')'); 
      System.out.println(str); 
     } 
    } 

}.start(); 
Thread.sleep(2000); 

}

輸出是:

100 
constructor : A$1() 

回答

16

這裏是你的程序打印出什麼我的系統上:

100 
constructor : A$1() 

所以構造有。但是,它是無參數的。從查看反彙編,會發生什麼情況是編譯器發現它不需要通過xrun(),因爲它的值在編譯時已知。

如果我更改代碼,如下所示:

public class A { 

    public static void test(final int x) throws InterruptedException { 
     new Thread() { 
      public void run() { 
       System.out.println(x); 
       for (Constructor<?> cons : this.getClass() 
         .getDeclaredConstructors()) { 
        StringBuilder str = new StringBuilder(); 
        str.append("constructor : ").append(cons.getName()) 
          .append("("); 
        for (Class<?> param : cons.getParameterTypes()) { 
         str.append(param.getSimpleName()).append(", "); 
        } 
        if (str.charAt(str.length() - 1) == ' ') { 
         str.replace(str.length() - 2, str.length(), ")"); 
        } else 
         str.append(')'); 
        System.out.println(str); 
       } 
      } 

     }.start(); 
     Thread.sleep(2000); 
     } 

    public static void main(String[] args) throws InterruptedException { 
     test(100); 
    } 

} 

獲取生成的構造是現在:

constructor : A$1(int) 

唯一的參數是x值。

27

在這種情況下,這是因爲100是一個常數。這會融入你的課堂。

如果更改x是:

final int x = args.length; 

...那麼你會在輸出中看到Test$1(int)。 (儘管這是它沒有被顯式聲明的是,捕捉更多的變數增加了參數的構造函數。)

+1

@Bohemian:鑑於我知道問題的由來,我認爲它是:) –