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

标签 java lambda

我想知道是否有一种方法可以在定义的同一表达式中直接调用 lambda 函数的 .apply().get()。当我想初始化一个可能是私有(private)的变量时,我想到了这个问题,但我不能将它声明为 final,因为该值是可以抛出异常的函数的返回值。例如,考虑 Files.size(path):

 final s = Files.size(path);
 // code that uses s

现在,如果我想为 s 使用默认值,如果有异常,我必须添加一个 try/catch,但这是一个声明和不是表达式:

s = 0;
try {
    s = Files.size();
}
catch (IOException e) {}

 // code that uses s

显而易见的解决方案是只声明一个包装 try/catch 的小辅助函数,例如getFileSizeOrZero。我还可以编写一个通用函数,将其包装为一般情况。这很好并且具有描述性,但是更局部的函数方法会更好。

在 C++ 中,我使用了 lambda:

const s = []() {
    try {
        return Files.size(path);
    } catch (...) {
        return 0;
    }
}();

所以我想知道这是否可以用 Java 完成。我能想到的最好的办法是

final int s = new IntSupplier() {
    @Override
    public int getAsInt() {
        try {
            return Files.size(path);
        }
        catch (IOException e) {
            return 0;
        }
    }
 }.getAsInt();

这似乎很有表现力,所以我希望有一些我不知道启用的语法

final int s = () -> {
    try {
        return Files.size(path);
    }
    catch (IOException e) {
        return 0;
    }
}.apply();

问题似乎是没有像C++中那样的函数调用运算符,所以必须有一个可以调用的命名成员函数。

最佳答案

您可以这样做,但您需要将匿名 lambda 显式转换为正确的类型。那是因为你需要将 lambda 的类型强制转换为特定的功能接口(interface),Java 无法猜测最终类型,例如:

final int x = ((IntSupplier)() -> 5).getAsInt();

如果你不喜欢它,你需要将它存储在一个变量中:

final IntSupplier xx = () -> 5;
final int x = xx.getAsInt();

关于java - 通过直接评估 lambda 来初始化变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47943103/

相关文章:

java - 当服务器抛出 IllegalArgrumentException 等应用程序异常时,预期响应是什么?

相同目录中的 Java 模块和资源

java - java中的用户模拟

c# - 在表达式树中,如何使用需要与结果进行比较的表达式,例如。指数?

Java lambda 只抛出表达式样式而不是语句样式

java - 动态调整文本区域大小以适应内容

java - lshistory 命令没有给出子文件夹的日志?

c# - 带返回值的匿名方法

c# - 如何使用 LINQ 将 List<string> 中的所有字符串转换为小写?

c# - 组合字符串时方法语法中的 Where 子句失败