Java 8 中“If/Throw, Else/Return”逻辑的简写?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26499904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shorthand for "If/Throw, Else/Return" logic in Java 8?
提问by Sam Berry
Is there a shorter syntax to if/throw else/return in Java 8? java.util.Optional
provides a means to accomplish this in one statement, but it requires creating an Optional
instance with every call that has a non-null reference.
在 Java 8 中是否有更短的 if/throw else/return 语法?java.util.Optional
提供了一种在一个语句中完成此操作的方法,但它需要Optional
为每个具有非空引用的调用创建一个实例。
Can this be accomplished in a single statement?
这可以在单个语句中完成吗?
public static MyEnum fromString(String value) {
MyEnum result = enumMap.get(value);
if (result == null)
throw new IllegalArgumentException("Unsupported value: " + value);
return result;
}
Optional Example (bad, requires Optional instance every time)
可选示例(不好,每次都需要可选实例)
public static MyEnum fromString(String value) {
return Optional.ofNullable(enumMap.get(value)).orElseThrow(
() -> new IllegalArgumentException("Unsupported value: " + value));
}
采纳答案by Holger
The impact of a temporary Optional
instance is negligible. Usually the JVM will detect its temporary nature and optimize away the instance. Even if the temporary instance creation is not optimized away, the impact of one single temporary object on the memory management is ridiculously low.
临时Optional
实例的影响可以忽略不计。通常 JVM 会检测它的临时性质并优化掉实例。即使临时实例的创建没有被优化掉,单个临时对象对内存管理的影响也是低得离谱的。
However, if the map is mutable, you can use the following trick:
但是,如果地图是可变的,您可以使用以下技巧:
public static MyEnum fromString(String value) {
return enumMap.computeIfAbsent(value, v -> {
throw new IllegalArgumentException("Unsupported value: " + v); });
}
Note that the Map
is not modified by this code but still must be mutable as an immutable map might throw an UnsupportedOperation
exception for the attempt to use computeIfAbsent
without ever checking whether the operation would really modify the map.
请注意,Map
此代码不会修改 ,但仍然必须是可变的,因为不可变映射可能会UnsupportedOperation
在尝试使用时抛出异常,computeIfAbsent
而无需检查操作是否真的会修改映射。
But in the end, there is nothing wrong with Optional
. But note that the code in your question is wrong. The lambda expression you pass to the method Optional.orElseThrow
is meant to supplythe desired exception, not to throw it:
但最终,没有任何问题Optional
。但请注意,您问题中的代码是错误的。您传递给该方法的 lambda 表达式Optional.orElseThrow
旨在提供所需的异常,而不是抛出它:
public static MyEnum fromString(String value) {
return Optional.ofNullable(enumMap.get(value)).orElseThrow(() ->
new IllegalArgumentException("Unsupported value: " + value) // just return it
);
}
回答by Misha
If you are willing to live with NullPointerException
, you can do:
如果你愿意和 一起生活NullPointerException
,你可以这样做:
public static MyEnum fromString(String value) {
return requireNonNull(enumMap.get(value), () -> "Unsupported: " + value);
}
This assumes import static java.util.Objects.requireNonNull
这假设 import static java.util.Objects.requireNonNull
Edit:
编辑:
If you are really particular about what type of exception you throw, just implement your own static utility method:
如果您真的很在意抛出什么类型的异常,只需实现您自己的静态实用程序方法:
static<T, X extends Throwable> T nonNullOrThrow(T val, Supplier<? extends X> exSupplier) throws X {
if (val != null) return val;
else throw exSupplier.get();
}
Then you'll be able to do
然后你就可以做
return nonNullOrThrow(enumMap.get(value), () -> new IllegalArgumentException("unsupported: " + k));