Java 使用Optional.of()有真正的原因吗?

Java 使用Optional.of()有真正的原因吗?,java,nullpointerexception,java-8,optional,Java,Nullpointerexception,Java 8,Optional,我已经读过为什么应该使用Optional.of()而不是Optional.ofNullable(),但是答案一点也不让我满意,所以我的问题略有不同: 如果您确定您的方法不返回null,那么为什么要使用可选的?据我所知,它或多或少的唯一目的是提醒“方法的用户”,他可能必须处理null-值。如果他不必处理null-值,为什么他要为可选值而烦恼呢 我这样问是因为我最近让我的服务层返回可选值而不是空值(在某些情况下)。我使用了Optional.of(),当它抛出空指针时,我非常困惑 我所做的一个例子:

我已经读过为什么应该使用
Optional.of()
而不是
Optional.ofNullable()
,但是答案一点也不让我满意,所以我的问题略有不同:

如果您确定您的方法不返回
null
,那么为什么要使用
可选的
?据我所知,它或多或少的唯一目的是提醒“方法的用户”,他可能必须处理
null
-值。如果他不必处理
null
-值,为什么他要为
可选值而烦恼呢

我这样问是因为我最近让我的服务层返回可选值而不是空值(在某些情况下)。我使用了
Optional.of()
,当它抛出空指针时,我非常困惑

我所做的一个例子:

Optional valueFromDB = getUserById("12");
User user = valueFromDB.get(); 

.....

public Optional<User> getUserById(String id) {
  //...
  return Optional.of(userRepository.findOne(id)); // NullPointerException!
}
可选值fromdb=getUserById(“12”);
User=valueFromDB.get();
.....
公共可选getUserById(字符串id){
//...
返回可选的.of(userRepository.findOne(id));//NullPointerException!
}
如果null不可能,我不明白为什么要用
可选的
来包装它。链接答案中的那个家伙说:“好吧,如果一个空指针发生了,它马上就发生了!”但我真的想要这样吗?如果
可选
的唯一目的是提醒获取此类对象的程序员记住
null
(他必须将其展开),为什么我要在包装时使用
NullPointerException


编辑:我需要编辑这个问题,因为它被标记为重复,即使我从一开始就链接了这个问题。我也解释了,为什么答案不让我满意,但现在我需要编辑我的文本并给出解释。 但这是我想问的问题的附录,因为我得到了5个答案,每个人都回答了不同的案例,但没有一个完全涵盖了我想问的问题:

是否有理由认为Optional.of(null)是不可能的,他们专门为null添加了Optional.of nullable()

使用流不应该是我实现想法的问题。 我从你的回答中得到了很多见解,谢谢你。但据我所知/阅读/理解,真正的问题直到现在才得到回答。
也许我应该问:“如果我们删除
Optional.of()
方法,并且在Java 9中只允许
Optional.of nullable()
,除了向后兼容性之外,还会有什么问题吗?”

我认为您的观点是正确的,如果您确信始终有一个返回值,那么就不应该使用Optional

但是您的方法不确定它是否总是返回值

考虑调用getUserById(-1)。(通常)没有具有此id的用户,您的userRepository将返回null

所以在这种情况下,您应该使用Optional.ofNullable


您将API设计原理与特定实现代码中的知识混为一谈。方法很有可能声明返回一个
可选的
,因为该值可能不存在,而在方法中的某个代码位置,它肯定存在。即

String content;
public Optional<String> firstMatch(String pattern) {
    Matcher m = Pattern.compile(pattern).matcher(content);
    return m.find()? Optional.of(m.group()): Optional.empty();
}
字符串内容;
公共可选第一匹配(字符串模式){
Matcher m=Pattern.compile(Pattern.Matcher(content);
返回m.find()?Optional.of(m.group()):Optional.empty();
}
此方法的返回类型表示可能不存在的
字符串
,而在创建
可选
实例的代码位置,可以知道该值是否存在。这里不是检测
null


类似地,在流API方法
findFirst()
findAny()
中,将在某一点上知道是否存在匹配元素,然而,在匹配
null
元素的情况下,支持将其存在转换为不存在,这显然是不受支持的,并且应该引发
NullPointerException
。因此,
Optional.of
将用于返回匹配元素,当使用
Stream.of((Object)null.findAny()时,您可以在堆栈跟踪中轻松识别该元素

Angelika Langer说,
Optional.ofNullable
只是一种方便的方法,从
Optional
调用其他两种静态方法。其实施方式如下:

return value == null ? empty() : of(value) ;
她还说,
Optional.ofNullable
最近被添加到API中

以下是她的德语文本:

因此,只有当null是一个错误时,我才会使用
Optional.of
,这应该尽早找到。这是塔吉尔·瓦列夫(Tagir Valeev)在书中所说的:

当您知道
值不能为空时,使用
可选.of(value)
的另一个原因是,如果您想对该
可选
执行额外的筛选操作

例如:

public static long getPageSizeFrom(HttpServletRequest request) {
    return Optional.of(request.getParameter("pageSize"))
                   .filter(StringUtils::isNumeric)
                   .map(Long::valueOf)
                   .filter(page::hasPageSize)
                   .orElse(page::getDefaultPageSize)
}

Optional是从函数式编程语言中引入的东西之一,它被抛到了面向对象和过程编程人员的膝上……这给他们带来了很多痛苦和痛苦

首先,快速链接到一篇博客文章(不是我写的),这有助于澄清这一问题:

可选与函数编程类型相关,如。由于强类型在函数式编程中的工作方式,使用该语言的程序员可能会说值可以是某物,也可以是零。这里,有事与无事实际上是不同的类型。任何需要a中的值的东西可能都必须同时处理这两个值——如果代码不能同时处理这两个值,那么它将无法编译

将该场景与C++对象语言(java、c、C++等)中的典型情况进行比较,其中对象可以有值,也可以为null。如果一个方法需要将空参数作为一个边缘情况来处理,那么您需要显式地编写该代码——并且是一个懒惰的程序员

return new Optional<>(value);
return new Optional<>(Objects.requireNonNull(value, "cannot be null!"));
public Optional<String> getSomeNullableValue() {
   if (defaultSituationApplies()) { return Optional.of("default value"); }
   else {
      String value = tryToGetValueFromNetworkOrNull();
      return Optional.ofNullable(value);
   }
}