java - 函数式 Java-8 lambda 与显式表达式报告编译器错误

标签 java lambda java-8

现在使用 java-8,我将一些显式声明转换为 lambda 表达式,并收到编译器错误。因此怀疑这是当前 java-8 版本 (b105) 的一个“bug”。

示例代码定义了两个使用和不使用 lambda 表达式的 Function 对象。两者都依赖于这些函数使用的谓词。虽然传统实现可以工作,但 lambda 版本会报告错误:

java: variable fileExists might not have been initialized

这并不是完全错误的,但是如果使用函数而不是创建函数本身,则谓词是相关的(因为显式版本运行良好)。 我应该报告错误(有人有链接吗?)还是我错过了什么?

public class FileOpener {

public FileOpener(Predicate<File> fileExists) {
    this.fileExists = fileExists;
}

final Predicate<File> fileExists;

final Function<File, FileInputStream> openLambda = file -> {
    try {
        return fileExists.test(file) ? new FileInputStream(file) : null;
    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    }
};

// this version compiles
final Function<File, FileInputStream> openFunction = new Function<File, FileInputStream>() {
    @Override
    public FileInputStream apply(File file) {
        try {
            return fileExists.test(file) ? new FileInputStream(file) : null;
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
};

}

最佳答案

正如 Edwin Dalorzo 所指出的,错误消息是正确的。初始化顺序在这里很重要。首先,字段初始值设定项按照源文件中出现的顺序执行,然后是构造函数。引用变量的 Lambda 捕获变量,对于最终变量(以及所有局部变量),它们捕获需要初始化变量的实际值。这符合 Java 语言规范,并且在 Java 8 中没有改变:

class SimpleTest
{
  SimpleTest()
  {
    first="a string";
  }
  final String first;
  String second=first;
}

在 Java 8 之前的版本中显示完全相同的行为。

关于java - 函数式 Java-8 lambda 与显式表达式报告编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19378621/

相关文章:

java - 在具体类中调用超接口(interface)的非抽象方法

java - 使用 Java8 匹配方法比较两个列表

java - 是否可以在 Java 中同时实现 ListIterator 和 Collection?

java - 错误: IOException - how to get more specific error

java - 将常规数据保存到文件

java - 如何使用 Java Stream map 实现不同类型之间的映射?

c++ - Lambda 语法或 gcc 错误的最后一刻更改?

java - Java 1.8 中并行流和顺序流的区别

Android Studio中的Java URLConnection.setRequestProperty似乎没有做任何事情

java - Spring - 为什么不使用 log4j2 XML 配置文件?