Java 8中“If / Throw,Else / Return”逻辑的简写?

时间:2014-10-22 03:32:48

标签: java java-8

在Java 8中if / throw else / return是否有更短的语法? java.util.Optional提供了在一个语句中完成此操作的方法,但它需要为每个具有非空引用的调用创建Optional实例。

这可以在一个声明中完成吗?

public static MyEnum fromString(String value) {
    MyEnum result = enumMap.get(value);
    if (result == null)
        throw new IllegalArgumentException("Unsupported value: " + value);
    return result;
}

可选示例(错误,每次都需要可选实例)

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(
        () -> new IllegalArgumentException("Unsupported value: " + value));
}

2 个答案:

答案 0 :(得分:28)

临时Optional实例的影响可以忽略不计。通常,JVM将检测其临时性质并优化实例。即使临时实例创建没有被优化,一个临时对象对内存管理的影响也是非常低的。

但是,如果地图是可变的,您可以使用以下技巧:

public static MyEnum fromString(String value) {
    return enumMap.computeIfAbsent(value, v -> {
        throw new IllegalArgumentException("Unsupported value: " + v); });
}

请注意,Map不会被此代码修改,但仍然必须是可变的,因为不可变的映射可能会为尝试使用UnsupportedOperation抛出computeIfAbsent异常,而无需检查是否操作真的会修改地图。


但最后,Optional没有任何问题。但请注意,您的问题中的代码是错误的。传递给方法Optional.orElseThrow的lambda表达式意味着提供所需的异常,而不是抛出它:

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(() ->
        new IllegalArgumentException("Unsupported value: " + value) // just return it
    );
}

答案 1 :(得分:3)

如果你愿意和NullPointerException一起生活,你可以这样做:

public static MyEnum fromString(String value) {
    return requireNonNull(enumMap.get(value), () -> "Unsupported: " + value);
}

这假定为import static java.util.Objects.requireNonNull

修改

如果你真的特别关注你抛出的异常类型,那么只需实现自己的静态实用程序方法:

static<T, X extends Throwable> T nonNullOrThrow(T val, Supplier<? extends X> exSupplier) throws X {
    if (val != null) return val;
    else throw exSupplier.get();
}

然后你就可以了

return nonNullOrThrow(enumMap.get(value), () -> new IllegalArgumentException("unsupported: " + k));