将最终变量传递给匿名类

在通过构造函数传递给匿名类的最终变量中 ,Jon Skeet提到变量通过自动生成的构造函数传递给匿名类实例。 在这种情况下,为什么我无法使用reflection看到构造函数:

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

以下是您的程序在我的系统上打印出来的内容:

 100 constructor : A$1() 

所以构造函数就在那里。 但是,它是无参数的。 从反汇编看,发生的情况是编译器发现它不需要将x传递给run()因为它的值在编译时是已知的。

如果我像这样更改代码:

 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的值。

在这种情况下,这是因为100是常数。 这会融入你的课堂。

如果您将x更改为:

 final int x = args.length; 

…然后你会在输出中看到Test$1(int) 。 (尽管它没有被显式声明。是的,捕获更多变量会为构造函数添加参数。)