将最终变量传递给匿名类

时间:2011-09-19 14:04:05

标签: java constructor inner-classes final anonymous-class

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
constructor : A$1()

2 个答案:

答案 0 :(得分:27)

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

如果您将x更改为:

final int x = args.length;

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

答案 1 :(得分:16)

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

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