【发布时间】:2013-10-15 10:15:56
【问题描述】:
现在我使用 java-8 将一些显式声明转换为 lambda 表达式并得到编译器错误。因此怀疑这是当前 java-8 版本 (b105) 的“错误”。
示例代码定义了两个使用和不使用 lambda 表达式的 Function 对象。两者都依赖于这些函数使用的谓词。虽然传统的实现可以工作,但 lambda 版本会报错:
java: 变量 fileExists 可能没有被初始化
这不是完全错误的,但是如果使用函数而不是创建函数本身,则谓词是相关的(因为显式版本运行良好)。 我应该报告错误(有人有链接吗?)还是我错过了什么?
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);
}
}
};
}
【问题讨论】:
-
在报告错误之前,我会 (a) 升级到最新版本并 (b) 在专用邮件列表中询问,也许是这个:mail.openjdk.java.net/mailman/listinfo/jdk8-dev lambda 的行为似乎是合理的,因为它是一个捕获 lambda,它可能需要在构造时知道它的参数值。
-
fileExists在哪里初始化?字段不是在构造函数之前初始化的吗? -
@assylias:“捕获”仅适用于局部变量。由于它不在方法中,因此没有局部变量。
-
@Edwin:fileExists 在构造函数中初始化,因此在 openLambda 之后。问题是它是否像 java8 报告的那样是一个严重的问题。
-
@Ditz 问题是
openLambda是一个实例字段,因此,在对象创建期间,它在构造函数之前被评估,因此fileExists那时没有初始化。