为什么Java lambda在实例字段初始化方面与嵌套类的处理方式不同?

时间:2016-10-05 18:30:42

标签: javac

使用javac 1.8.0_77这个类不能编译:

import java.util.function.*;
public class xx {
    final Object obj;

    final Supplier<Object> supplier1 = new Supplier<Object>() {
        @Override
        public Object get() {
            return xx.this.obj;
        }
    };

    final Supplier<Object> supplier2 = () -> { return this.obj; };

    xx(Object obj) {
        this.obj = obj;
    }
}

这是错误:

xx.java:12: error: variable obj might not have been initialized
    final Supplier<Object> supplier2 = () -> { return this.obj; };
                                                          ^
1 error

问题:

  1. 根据JLS生成此错误是否正确?
  2. 如果是这样,那么JLS在这方面处理@FunctionalInterface lamba实现(supplier2)与其等效内部类实现(supplier1)的区别是什么原因?

1 个答案:

答案 0 :(得分:2)

浏览JSR 335中的JLS更改,这看起来像是对我的疏忽:

事实上,第16章中唯一的变化是(使用粗体字面添加):

  

在本章的其余部分中,除非另有明确说明,否则我们将编写V代表范围内(6.3)局部变量或空白最终字段(对于规则而言明确的分配)或空白的最终变量(对于明确的未分配规则)

在底线,编译器似乎没有抱怨lambda案例,但为了保持一致性,JLS也应该修改以涵盖这种情况。

修改:OpenJDK已经为此spec bug,我们发言时正在提出更改。