首先检查这两个方法的声明。
1) OrElse:执行逻辑并将结果作为参数传递。
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: 如果可选值中的值为空,则执行逻辑
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
对上述声明的一些解释:
“Optional.orElse”的参数总是被执行,而不管可选对象的值(null、空或有值)。使用“Optional.orElse”时请务必牢记上述几点,否则在以下情况下使用“Optional.orElse”可能会非常危险。
Risk-1) 日志记录问题: 如果 orElse 中的内容包含任何日志语句:
在这种情况下,您最终将每次都记录它。
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
风险 2) 性能问题: 如果 orElse 中的内容很耗时:
时间密集型内容可以是任何 i/o 操作 DB 调用、API 调用、文件读取。如果我们把这样的内容放在 orElse() 中,系统最终会执行一段无用的代码。
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
风险 3) 非法状态或错误问题: 如果 orElse 中的内容正在改变某些对象状态:
我们可能会在另一个地方使用相同的对象,比如说在 Optional.map 函数中,它可能会使我们陷入严重的错误。
List<Model> list = new ArrayList<>();
Optional.of(getModel())
.map(x -> {
})
.orElse(get(list));
get(List < String > list) {
log.error("No Data found, Returning default");
list.add(defaultValue);
return defaultValue;
}
那么,我们什么时候可以使用 orElse()?
当默认值是某个常量对象枚举时,最好使用 orElse。在上述所有情况下,我们可以使用 Optional.orElseGet()(仅在 Optional 包含空值时执行)而不是 Optional.orElse()。为什么??在 orElse 中,我们传递了默认结果值,但在 orElseGet 中,我们传递了 Supplier 和 Supplier 的方法只有在 Optional 中的值为 null 时才会执行。
本文的主要内容:
- 如果包含任何日志语句,请勿使用“Optional.orElse”。
- 如果包含时间密集型逻辑,请勿使用“Optional.orElse”。
- 如果“Optional.orElse”正在改变某些对象状态,请不要使用它。
- 如果我们必须返回一个常量枚举,请使用“Optional.orElse”。
- 在第 1,2 和第 3 点提到的情况下首选“Optional.orElseGet”。
我在第 2 点 (“Optional.map/Optional.orElse” != “if/else”) 我的中型博客中对此进行了解释。 Use Java8 as a programmer not as a coder