随着Java-11的发布,当我们可以直接检查数字是否不为空或不等于特定数字时,为什么我们还要使用带有optionalLong / OptionalDouble的orElseThrow和其他Optional Types。
另外,我们做的是空检查,这比抛出异常要好?
可能无法可视化optionalTypes和orElseThrow的真正用法。
用于orElseThrow的Javadoc。
发布于 2019-07-31 18:30:24
当我们可以直接检查一个数字是否不为空或者不等于一个特定的数字时,为什么我们要使用带有optionalLong / OptionalDouble的orElseThrow。
实际上并非如此,Optional是为返回类型设计的,而不是用来检查输入参数的。在后一种情况下,检查not null或range有效性(对于原语)更有意义。
此外,这些功能并不新鲜。Java 8已经引入了这些函数。
为了说明OptionalLong.orElseThrow()的重要性,假设您从一个方法中搜索了一个long id,但可能找不到该id。
下面是处理未找到值的情况的代码。
如果没有OptionalLong,您应该选择一个任意的长值来表示not found结果:
long id = compute(); // returns -1. By hopping that it not a valid id...然后,在客户端,您必须深入研究compute()的实现,以了解id值是否可以为空,以及是否可以,哪个值表示为空。
最后,你可以这样写:
if (id == -1){
throw new IllegalArgumentException("the id is mandatory");
}假设明天的-1是一个有效的id,那么您应该同时更改实现和客户端代码以意识到这一点:根本无法维护,并且非常容易出错。
使用OptionalLong时,这种方法更加健壮:
OptionalLong optId = compute(); // returns OptionalLong.empty();作为compute()的客户,您知道id可能是空的(Optional语义),也知道如何以标准的方式处理它: Optional`展开函数。
long mandatoryId = optId.orElseThrow( ()-> new IllegalArgumentException("the id is mandatory"); 在这里,OptionalLong甚至Optional<Long>提供了三重优势(关于它们之间的差异,我建议使用the excellent answer of Nishant):
-1 living documentation传达和处理空返回(Optional及其函数)的方式相比)但一般而言,中包含Object的Optional“仅”具有以下两个优点:
Optional及其函数)发布于 2019-07-31 18:31:29
我从com.google.common.io应用程序接口中随机选择了一个方法来演示Optional<Long>的用法。它们使用自己的Optional类型,但概念是相同的。
@Override
public Optional<Long> sizeIfKnown() {
if (file.isFile()) {
return Optional.of(file.length());
} else {
return Optional.absent();
}
}由于缺少OptionalLong,它们自动将返回long的file.length()包装到Optional<Long>中。他们不希望sizeIfKnown抛出异常。他们不希望sizeIfKnown引入一个神奇的返回值来表示缺少值。
相反,他们想说“我们返回一个long,否则什么都不返回”。
使用Java11,它看起来会更干净一些,也会更简单一些
@Override
public OptionalLong sizeIfKnown() {
if (file.isFile()) {
return OptionalLong.of(file.length());
} else {
return OptionalLong.empty();
}
}关于orElseThrow,它是Java8中引入的相对较旧的特性,用于以函数方式控制执行流程。它所做的正是您所描述的:一个null检查和一条throw语句。
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}发布于 2019-07-31 18:40:58
我想在davidxxx的回答中添加以下内容
为了保持与基元流的一致性,API中包含了基元可选参数。请参阅此答案- OptionalInt vs Optional。
但是,不鼓励使用它们,因为它们缺少Optional类中最有用的方法map、flatMap和filter方法。
而且,就像streams一样,optional不能与其原始副本组合在一起,因此如果一个方法返回了OptionalDouble,则不能将其作为方法引用传递给另一个optional的flatMap方法。
https://stackoverflow.com/questions/57288280
复制相似问题