【问题标题】:Passing final variables to anonymous classes将最终变量传递给匿名类
【发布时间】:2011-11-20 07:03:22
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    如果您将x 更改为:

    final int x = args.length;
    

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

    【讨论】:

    • @Bohemian:鉴于我知道问题的根源,我认为是:)
    【解决方案2】:

    这是您的程序在我的系统上打印的内容:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多