我想知道是否有一种方法可以直接在定义的相同表达式中调用.apply()或.get()使用lambda函数.当我想初始化一个可能是私有的变量时,我想到了这个问题,但我无法将其声明为final,因为该值是可以抛出异常的函数的返回值.例如,考虑Files.size(path):
final s = Files.size(path);
// code that uses s
Run Code Online (Sandbox Code Playgroud)
现在,如果我想使用默认值,s如果有异常,我必须添加一个try/catch,但这是一个语句,而不是一个表达式:
s = 0;
try {
s = Files.size();
}
catch (IOException e) {}
// code that uses s
Run Code Online (Sandbox Code Playgroud)
显而易见的解决方案是只声明一个包装try/catch的小辅助函数,例如getFileSizeOrZero.我也可以编写一个通用函数来包装它作为一般情况.这很好并且具有描述性,但更局部的函数方法会更好.
在C++中,我使用了lambdas:
const s = []() {
try {
return Files.size(path);
} catch (...) {
return 0;
}
}();
Run Code Online (Sandbox Code Playgroud)
所以我想知道这是否可以用Java完成.我能想到的最好的是
final int s = new IntSupplier() {
@Override
public int getAsInt() {
try {
return Files.size(path);
}
catch (IOException e) {
return 0;
}
}
}.getAsInt();
Run Code Online (Sandbox Code Playgroud)
这似乎很有表现力,所以我希望有一些我不知道启用的语法
final int s = () -> {
try {
return Files.size(path);
}
catch (IOException e) {
return 0;
}
}.apply();
Run Code Online (Sandbox Code Playgroud)
似乎问题是在C++中没有函数调用操作符,因此必须有一个可以调用的命名成员函数.
您可以这样做,但您需要显式地将匿名lambda强制转换为正确的类型.那是因为你需要将lambda的类型强制转换为特定的功能接口,Java无法猜测最终的类型,例如:
final int x = ((IntSupplier)() -> 5).getAsInt();
Run Code Online (Sandbox Code Playgroud)
如果你不喜欢它,你需要将它存储在一个变量中:
final IntSupplier xx = () -> 5;
final int x = xx.getAsInt();
Run Code Online (Sandbox Code Playgroud)