如注释中所述,其中一些在Java 8中变得无关紧要,在Java 8中final可以隐式使用。但是,只能在匿名内部类或lambda表达式中使用有效的最终变量。
这基本上是由于Java管理闭包的方式。
创建匿名内部类的实例时,该类中使用的任何变量都将通过自动生成的构造函数复制其值。这样避免了编译器不得不自动生成各种额外的类型来保存“局部变量”的逻辑状态,例如C#编译器确实…(当C#在匿名函数中捕获变量时,它实际上捕获了变量-闭包可以通过该方法的主体看到的方式更新变量,反之亦然。)
由于该值已被复制到匿名内部类的实例中,因此如果变量的其余部分可以被该方法的其余部分修改,则看起来会很奇怪-您可能会发现代码似乎在使用过期的变量(因为这实际上是将要发生的事情……您将使用在不同时间拍摄的副本)。同样,如果您可以在匿名内部类中进行更改,则开发人员可能希望这些更改在封闭方法的正文中可见。
将变量设为final消除了所有这些可能性-由于根本无法更改该值,因此您无需担心此类更改是否可见。允许方法和匿名内部类相互查看更改的唯一方法是使用某种描述的可变类型。这可能是封闭的类本身,一个数组,一个可变的包装器类型……诸如此类。基本上,这有点像一种方法与另一种方法之间的通信:调用者看不到对一个方法的参数所做的更改,但是可以看到对参数所引用的对象所做的更改。
如果您想对Java和C#闭包之间的更详细的比较感兴趣,请参阅我的文章。我想在这个答案中专注于Java方面:)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)