使用复杂表达式

时间:2017-05-18 14:57:07

标签: java lambda anonymous-inner-class

Java 8中是否有办法同时使用复杂表达式的结果声明和初始化final变量?

换句话说,可能会出现以下情况吗?

final int x = [capturedVariable] {
    switch (capturedVariable) {
    case 1: return 42;
    case 2: return 84;
    default: return 66;
    }
};

虽然语法显然是“有创意的”,但我希望意图很明确。

编辑1:虽然这个特殊的例子可以使用三元运算符编写,但它只是一个复杂表达式的例子,我正在寻找一个通用的解决方案。

编辑2:查看这个问题可能是一个不那么有争议的方式如下:在Java 8中同时声明和调用lambda / closure的语法是什么?

3 个答案:

答案 0 :(得分:3)

我不知道Java 8在这里是如何相关的,你可以在多个地方分配一个最终变量,只要你总是分配它并且只分配一次,例如这是合法的Java代码(假设等等)是一个有效的布尔值):

final int test;
if (blah) {
  test = 1;
} else {
  test = 2;
}

只要编译器能够确定地证明您始终只对属性进行一次初始化,表达式就可以像您一样复杂。 (例如循环会使其失败)。

答案 1 :(得分:2)

似乎过度杀伤,但您可以使用Supplier

final int x = new Supplier<Integer>() {
    public Integer get() {
        // Complexity here
        return result;
    }
}.get();

我确定我的Java-fu很弱 (我猜不是),但我能获得lambda版本的唯一方法工作是在某处具有可重用的call实用程序功能:

class Utils {
    public static <T> T call(Supplier<T> x) {
        return x.get();
    }
}

......然后:

final int x = Utils.call(() -> {
    // Complexity here
    return result;
});

Matthias在评论中指出(由Aominè改进),您可以避免使用该中间函数,但它并不比上面的第一个解决方案更漂亮:

final int x = ((Supplier<Integer>) () -> {
    // Complexity here
    return result;
}).get();

......但至少它不需要生成一个类。

答案 2 :(得分:0)

您可以创建自己的接口,创建一个init方法,该方法接受一个init并返回另一个int,例如:

Init i = (x) -> {
    switch (x) {
        case 1:
            return 42;
        case 2:
            return 84;
        default:
            return 66;
    }
};
final int x = i.init(1);

...

interface Init {
    int init(int x);
}