通过直接评估lambda来初始化变量

Jen*_*ens 7 java lambda

我想知道是否有一种方法可以直接在定义的相同表达式中调用.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++中没有函数调用操作符,因此必须有一个可以调用的命名成员函数.

Jac*_*ack 5

您可以这样做,但您需要显式地将匿名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)