2011-09-19 3 views
17

final variable passed to anonymous class via constructor에서 Jon Skeet은 변수가 자동 생성 생성자를 통해 익명 클래스 인스턴스에 전달됨을 언급했습니다. 내가 왜 그 경우에 반사를 사용하여 생성자 볼 수 없을 것입니다 :최종 변수를 익명 클래스에 전달

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)가 일정하기 때문에이 경우

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

, 그것은이다. 그것은 수업에 구워집니다.

당신이 x을 변경하는 경우

가되게합니다 :
final int x = args.length; 

가 ... 다음 출력에 Test$1(int)를 볼 수 있습니다. (. 이것은 명시 적으로 선언 그리고 네, 많은 변수를 캡처하는 생성자에 매개 변수를 추가하지 않을에도 불구하고.)

여기
+1

@ 보헤미안 : 내가 질문의 기원을 알고 있다고 생각하면, 나는 그것이라고 생각한다. :) –