首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么选择Double/Double和orElseThrow?

为什么选择Double/Double和orElseThrow?
EN

Stack Overflow用户
提问于 2019-07-31 18:07:20
回答 5查看 572关注 0票数 5

随着Java-11的发布,当我们可以直接检查数字是否不为空或不等于特定数字时,为什么我们还要使用带有optionalLong / OptionalDoubleorElseThrow和其他Optional Types

另外,我们做的是空检查,这比抛出异常要好?

可能无法可视化optionalTypesorElseThrow的真正用法。

用于orElseThrow的Javadoc。

EN

回答 5

Stack Overflow用户

发布于 2019-07-31 18:30:24

当我们可以直接检查一个数字是否不为空或者不等于一个特定的数字时,为什么我们要使用带有optionalLong / OptionalDouble的orElseThrow。

实际上并非如此,Optional是为返回类型设计的,而不是用来检查输入参数的。在后一种情况下,检查not null或range有效性(对于原语)更有意义。

此外,这些功能并不新鲜。Java 8已经引入了这些函数。

为了说明OptionalLong.orElseThrow()的重要性,假设您从一个方法中搜索了一个long id,但可能找不到该id。

下面是处理未找到值的情况的代码。

如果没有OptionalLong,您应该选择一个任意的长值来表示not found结果:

代码语言:javascript
复制
long id = compute();  // returns -1. By hopping that it not a valid id...

然后,在客户端,您必须深入研究compute()的实现,以了解id值是否可以为空,以及是否可以,哪个值表示为空。

最后,你可以这样写:

代码语言:javascript
复制
if (id == -1){
   throw  new IllegalArgumentException("the id is mandatory");
}

假设明天的-1是一个有效的id,那么您应该同时更改实现和客户端代码以意识到这一点:根本无法维护,并且非常容易出错。

使用OptionalLong时,这种方法更加健壮:

代码语言:javascript
复制
OptionalLong optId = compute(); // returns OptionalLong.empty();

作为compute()的客户,您知道id可能是空的(Optional语义),也知道如何以标准的方式处理它: Optional`展开函数。

代码语言:javascript
复制
long mandatoryId = optId.orElseThrow( ()-> new IllegalArgumentException("the id is mandatory");  

在这里,OptionalLong甚至Optional<Long>提供了三重优势(关于它们之间的差异,我建议使用the excellent answer of Nishant):

  • living documentation of the emptiness return
  • 客户端传达空值的可靠方式(与-1 living documentation传达和处理空返回(Optional及其函数)的方式相比)

但一般而言,中包含ObjectOptional“仅”具有以下两个优点:

  • living documentation of the emptiness return
  • 传达和处理空返回的标准方法(Optional及其函数)
票数 3
EN

Stack Overflow用户

发布于 2019-07-31 18:31:29

我从com.google.common.io应用程序接口中随机选择了一个方法来演示Optional<Long>的用法。它们使用自己的Optional类型,但概念是相同的。

代码语言:javascript
复制
@Override
public Optional<Long> sizeIfKnown() {
  if (file.isFile()) {
    return Optional.of(file.length());
  } else {
    return Optional.absent();
  }
}

由于缺少OptionalLong,它们自动将返回longfile.length()包装到Optional<Long>中。他们不希望sizeIfKnown抛出异常。他们不希望sizeIfKnown引入一个神奇的返回值来表示缺少值。

相反,他们想说“我们返回一个long,否则什么都不返回”。

使用Java11,它看起来会更干净一些,也会更简单一些

代码语言:javascript
复制
@Override
public OptionalLong sizeIfKnown() {
  if (file.isFile()) {
    return OptionalLong.of(file.length());
  } else {
    return OptionalLong.empty();
  }
}

关于orElseThrow,它是Java8中引入的相对较旧的特性,用于以函数方式控制执行流程。它所做的正是您所描述的:一个null检查和一条throw语句。

代码语言:javascript
复制
if (value != null) {
    return value;
} else {
    throw exceptionSupplier.get();
}
票数 3
EN

Stack Overflow用户

发布于 2019-07-31 18:40:58

我想在davidxxx的回答中添加以下内容

为了保持与基元流的一致性,API中包含了基元可选参数。请参阅此答案- OptionalInt vs Optional

但是,不鼓励使用它们,因为它们缺少Optional类中最有用的方法mapflatMapfilter方法。

而且,就像streams一样,optional不能与其原始副本组合在一起,因此如果一个方法返回了OptionalDouble,则不能将其作为方法引用传递给另一个optional的flatMap方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57288280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档