引用来自 lambda 表达式的最后一个字段 [英] Reference to the final field from lambda expression

查看:24
本文介绍了引用来自 lambda 表达式的最后一个字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我发现匿名类和 lambda 表达式之间的细微差别:

Recently I've found a subtle difference between anonymous class and lambda expression:

public class FinalTest {
    final Runnable x = new Runnable() {
        @Override
        public void run() {
            System.out.println(x.hashCode());
        }
    };

    final Runnable y = () -> System.out.println(y.hashCode()); 
}

通常 lambdas 相当于匿名类.甚至我的 Eclipse IDE 也有重构将 x 转换为 lambda(它变得完全像 y)并将 y 转换为匿名类(它变成完全像 x).然而,lambda 给了我一个编译错误,而匿名类可以完美编译.错误信息如下所示:

Usually lambdas are equivalent to the anonymous classes. Even my Eclipse IDE has the refactoring to convert the x to lambda (it becomes exactly like y) and convert y to anonymous class (it becomes exactly like x). However the lambda gives me a compilation error while anonymous class can be perfectly compiled. The error message looks like this:

>javac FinalTest.java
FinalTest.java:9: error: self-reference in initializer
    final Runnable y = () -> System.out.println(y.hashCode());
                                                ^
1 error

那么问题是:为什么会有这种差异?

So the question is: why there's such difference?

推荐答案

这与 JLS #8.3.3 处理前向引用.特别是,如果您使用完全限定的名称,它会编译(因为该规则的第三个条件变为 false 使用是 C 的实例变量初始值设定项或 C 的实例初始值设定项中的简单名称):

This has to do with JLS #8.3.3 dealing with forward references. In particular, if you use a fully qualified name it compiles (because the third condition of that rule becomes false The use is a simple name in either an instance variable initializer of C or an instance initializer of C):

final Runnable y = () -> System.out.println(this.y.hashCode());

在匿名类的情况下,第四个条件(C 是最里面的类或封闭使用的接口)不成立,因为封闭类是匿名类本身.

In the case of the anonymous class, the fourth condition (C is the innermost class or interface enclosing the use) is not true because the enclosing class is the anonymous class itself.

这篇关于引用来自 lambda 表达式的最后一个字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆