Why are only final variables accessible in anonymous class?
###问题 写JAVA的人都知道这样的一个事实“在匿名类里面,只能使用final型变量或者外部类的成员变量”。那么有谁知道,为什么是这样的?
前几天,正好在忙复习final变量的问题。就想到了这个问题。于是Google了下,万能的stackoverflow里面给出了一个答案,
答案的第一句话,“It’s basically due to the way Java manages closures.”。
闭包-----恰好之前在读on lisp的时候,也看到了这个概念。有些印象,但还不是很熟。所以就顺便再复习了下。发现了一个介绍闭包很不错的文章。
在这篇文章中,主要推荐是这个定义
闭包是由函数和与其相关的引用环境组合而成的实体。比如参考资源中就有这样的的定义:在实现深约束(注2)时,需要创建一个能显式表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体被称为闭包。
既然闭包是闭包是函数和引用环境的组合,那他面临一个问题。如何才能正确执行闭包呢?
- 简单的办法是在函数定义时捕获当时的引用环境,并与函数代码组合成一个整体。当把这个整体当作函数调用时,先把其中的引用环境覆盖到当前的引用环境上,然后执行具体代码,并在调用结束后恢复原来的引用环境。这样就保证了函数定义和执行时的引用环境是相同的。这种由引用环境与函数代码组成的实体就是闭包。
- 当然如果编译器或解释器能够确定一个函数在定义和运行时的引用环境是相同的(注 3),那就没有必要把引用环境和代码组合起来了,这时只需要传递普通的函数就可以了。
看到这里,我释然了:看上去,方法1就是外部类的成员变量,而final型变量使用的是方法2. 这就印证了最一开始的那个答案。
但是我还是强调一下,JAVA里的匿名类,仅仅是模拟了闭包。更详细的闭包,以及闭包的神奇之处还需要下去仔细研究。以后另开一篇文章详细说明吧。
最后,引用一句话结尾总结
“对象是附有行为的数据,而闭包是附有数据的行为”