Passing final variables to anonymous classes

后端 未结 2 1397
我寻月下人不归
我寻月下人不归 2020-12-29 06:51

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.

相关标签:
2条回答
  • 2020-12-29 07:38

    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.

    0 讨论(0)
  • 2020-12-29 07:41

    In this case, it's because 100 is a constant. That gets baked into your class.

    If you change x to be:

    final int x = args.length;
    

    ... then you'll see Test$1(int) in the output. (This is despite it not being explicitly declared. And yes, capturing more variables adds parameters to the constructor.)

    0 讨论(0)
提交回复
热议问题