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

2022-09-01 05:21:20

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

这可以在单个语句中完成吗?

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));
}

答案 1

临时实例的影响可以忽略不计。通常,JVM 会检测其临时性并优化实例。即使没有优化临时实例创建,单个临时对象对内存管理的影响也低得离谱。另请参阅 Java 中可选<T>的 GC 开销Optional

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

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

请注意,此代码不会修改 ,但仍必须是可变的,因为不可变映射可能会引发异常以供尝试使用,而无需检查该操作是否真的会修改映射。MapUnsupportedOperationcomputeIfAbsent


但最终,没有错。但请注意,您的问题中的代码是错误的。传递给该方法的 lambda 表达式旨在提供所需的异常,而不是引发它:OptionalOptional.orElseThrow

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

答案 2

如果你愿意和 一起住,你可以做: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));

推荐