将最终变量传递给匿名类 [英] Passing final variables to anonymous classes

查看:149
本文介绍了将最终变量传递给匿名类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最终变量通过构造函数传递给匿名类 ,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() =''){
str.replace(str.length() - 2,str.length(),));
} else
str.append(')');
System.out.println(str);
}
}

} .start();
Thread.sleep(2000);

}



/ p>

  100 
构造函数: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() =''){
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);
}

}

生成的构造函数现在:

 构造函数:A $ 1(int)

唯一的参数是 x 的值。


In final variable passed to anonymous class via constructor, Jon Skeet mentioned that variables are passed to the anonymous class instance via an auto-generated constructor. Why would I not be able to see the constructor using reflection in that case:

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

}

The output is:

100
constructor : A$1()

解决方案

Here is what your program prints out on my system:

100
constructor : A$1()

So the constructor is there. However, it is parameterless. From looking at the disassembly, what happens is that the compiler figures out that it doesn't need to pass x to run() since its value is known at compile time.

If I change the code like so:

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

}

The constructor that gets generated is now:

constructor : A$1(int)

The sole argument is the value of x.

这篇关于将最终变量传递给匿名类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆