java – 函数对象的内部类中的变量/对象会发生什么?

我有一个函数multi2,它返回内部类Inner作为Object.

会发生什么 – 保存在哪里以及如何访问它?

public class C {
    private static Object multi2(final int a) {
        class Inner {
            public int hashCode() {
                return 2*a;
            }
        }
        return new Inner();     // What happens to a?
                                // Who allocates a?
                                // Can I Access a?
    }

    public static void main(String[] args) {
        Object o = multi2(6);
        System.out.println("o.hashCode() = " + o.hashCode());

        o = multi2(4);
        System.out.println("o.hashCode() = " + o.hashCode());
    }
}
最佳答案
在实现级别发生的是,a的值的副本保存在C.Inner类的编译版本中声明的合成实例变量中.

a的值通过额外的参数传递给编译的Inner构造函数.

C.Inner.hashCode方法使用合成变量的值.访问Inner.hashCode的源代码中的a转换为访问编译代码中的相应合成变量.

外部作用域中的变量必须为final1.合成变量必须是Inner类中的final2.这保持了(可能)Inner类的多个实例看到相同变量的错觉. (它们不是,但由于变量无法更改,因此内部类的代码无法区分.)

如果使用javap查看已编译示例的字节码,您将看到用于在外部类和内部类中实现此操作的机制.

1 – 或从Java 8开始有效的最终结果.

2 – 如果a可以通过Inner方法进行变异,那么具有相同外部类的两个Inner实例需要共享一个可变变量,其生命周期(现在)长于multi2调用的堆栈帧.这需要以某种方式将堆栈变量转换为堆栈中的变量.这将是昂贵和复杂的.

转载注明原文:java – 函数对象的内部类中的变量/对象会发生什么? - 代码日志