2011-09-19 7 views
17

Trong final variable passed to anonymous class via constructor, Jon Skeet đã đề cập rằng các biến được chuyển đến cá thể lớp ẩn danh thông qua một hàm tạo được tạo tự động. Tại sao tôi không thể nhìn thấy các nhà xây dựng sử dụng phản chiếu trong trường hợp đó:Chuyển biến cuối cùng cho các lớp ẩn danh

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); 

}

Đầu ra là:

100 
constructor : A$1() 

Trả lời

16

Đây là những gì chương trình của bạn sẽ in ra trên hệ thống của tôi:

100 
constructor : A$1() 

Vì vậy, các nhà xây dựng là có . Tuy nhiên, nó là vô nghĩa. Từ việc xem xét việc tháo gỡ, điều xảy ra là trình biên dịch tính ra rằng nó không cần phải vượt qua x đến run() vì giá trị của nó được biết đến lúc biên dịch.

Nếu tôi thay đổi mã như vậy:

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); 
    } 

} 

Các constructor đó được tạo ra bây giờ là:

constructor : A$1(int) 

Đối số duy nhất là giá trị của x.

27

Trong trường hợp này, đó là vì 100 là một hằng số. Điều đó được nướng vào lớp học của bạn.

Nếu bạn thay đổi x là:

final int x = args.length; 

... sau đó bạn sẽ thấy Test$1(int) trong đầu ra. (Đây là mặc dù nó không được khai báo rõ ràng Và vâng, chụp biến hơn thêm tham số để các nhà xây dựng..)

+1

@Bohemian: Do tôi biết nguồn gốc của câu hỏi, tôi nghĩ rằng đó là :) –