首先,检查两个方法的声明。
1) OrElse:执行逻辑并将结果作为参数传递。
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet:如果optional中的value为空,则执行逻辑
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
关于上述声明的解释:
可选的参数。orElse "总是被执行,而不管可选对象的值(null, empty或with value)。在使用“可选”时,一定要考虑到上述几点。orElse”,否则使用“Optional”。“orElse”在以下情况下可能非常危险。
风险-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)非法状态或Bug问题:如果orElse内部的内容正在改变某些对象状态:
我们可能会在另一个地方使用相同的对象,比如在Optional内部。地图功能,它会让我们陷入一个严重的错误。
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。在上述所有情况下,我们都可以使用option . orelseget()(仅在Optional包含空值时执行)而不是option . orelse()。为什么? ?在orElse中,我们传递默认的结果值,但在orElseGet中,我们传递Supplier和Supplier的方法,只有当Optional中的值为空时才执行。
这里的关键要点是:
不要使用“可选”。orElse”,如果它包含任何日志语句。
不要使用“可选”。orElse”,如果它包含时间密集型逻辑。
不要使用“可选”。如果它正在改变某个对象状态,则使用orElse。
使用“可选的。orElse”如果我们必须返回一个常量,enum。
更喜欢“可选的。orElseGet”在1、2和3点提到的情况下。
我在第2点(“Optional.map/Optional。orElse " != " if/else ")我的媒体博客。作为程序员使用Java8,而不是作为编码器