为什么匿名类可以访问封闭类的非final类成员

use*_*800 13 java closures final anonymous-class

我们知道只能在匿名类中访问最终的局部变量,这里有一个很好的理由:为什么在匿名类中只能访问最终变量?.

但是,我发现如果变量是封闭类的成员字段,匿名类仍然可以访问非final变量:如何从匿名类内部访问封闭的类实例变量?

我很迷惑.我们确保只能在匿名类中访问最终的局部变量,因为我们不希望变量在匿名类和本地函数之间不同步.如果我们尝试访问匿名类中的非最终封闭类成员,则同样的理由应该适用于该情况.

为什么不关注呢?

Y.S*_*Y.S 7

在局部变量的情况下,变量的副本是匿名类实例接收的内容.因此,final必须在匿名类中使用局部变量之前进行局部变量,以便以后可能不会更改其值.

对于封闭类的成员字段,没有副本.相反,匿名类获取对封闭类的引用,从而访问外部类的任何/所有成员字段和方法.因此,即使字段的值发生更改,更改也会反映在匿名类中,因为它是相同的引用.

我很迷惑.我们确保只能在匿名类中访问最终的局部变量,因为我们不希望变量在匿名类和本地函数之间不同步.如果我们尝试访问匿名类中的非最终封闭类成员,则同样的理由应该适用于该情况.

如你所见,情况并非如此.复制仅针对局部变量,而不针对封闭类的成员字段.当然,原因是匿名类包含对封闭类的隐式引用,并且通过该引用它可以访问外部类的任何/所有成员字段和方法.

引用以下链接:

成员变量在封闭对象的生命周期中存在,因此可以由内部类实例引用.但是,局部变量仅在方法调用期间存在,并且由编译器以不同方式处理,因为它的隐式副本是作为内部类的成员生成的.在不声明局部变量fi​​nal的情况下,可以更改它,导致细微的错误,因为内部类仍然引用该变量的原始值.

参考文献:

1. 为什么非最终的"局部"变量不能在内部类中使用,而是封闭类的非最终字段可以?.