提问人:whirlwin 提问时间:7/29/2015 最后编辑:Andrew Tobilkowhirlwin 更新时间:5/11/2023 访问量:214995
为什么使用 Optional.of 而不是 Optional.ofNullable?
Why use Optional.of over Optional.ofNullable?
问:
使用 Java 8 类时,有两种方法可以将值包装在可选值中。Optional
String foobar = <value or null>;
Optional.of(foobar); // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException
我知道是唯一安全的使用方式,但为什么存在呢?为什么不随时使用并保持安全呢?Optional.ofNullable
Optional
Optional.of
Optional.ofNullable
答:
你的问题是基于这样的假设,即可能抛出的代码比可能不会抛出的代码更糟糕。这种假设是错误的。如果您希望由于程序逻辑而永远不会为 null,那么最好使用它,因为您会看到一个 这将表明您的程序存在错误。如果你使用并且恰好是由于错误,那么你的程序将默默地继续错误地工作,这可能是一个更大的灾难。这样一来,错误可能会在很久以后发生,并且更难理解它是在什么时候出错的。NullPointerException
foobar
Optional.of(foobar)
NullPointerException
Optional.ofNullable(foobar)
foobar
null
评论
Optional.of(foobar)
”。这似乎有点奇怪 - 当我们知道该值在任何情况下都不会存在时,那么为什么不使用该值本身,而不是将其包装在一个 ?null
Optional
Optional
null
Optional.isPresent() == false
return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));
list
null
此外,如果您知道如果 object 为 null,您的代码应该不起作用,则可以使用 Optional.orElseThrow
引发异常
String nullName = null;
String name = Optional.ofNullable(nullName)
.orElseThrow(NullPointerException::new);
// .orElseThrow(CustomException::new);
评论
String name = Objects.requireNonNull(nullName);
NullPointerException
null
new NullNameException("meaningful msg")
无论如何,可选应主要用于服务的结果。在服务中,你知道你手头有什么,如果你有结果,则返回 Optional.of(someValue),如果没有,则返回 Optional.empty()。在这种情况下,someValue 永远不应为 null,并且仍然返回 Optional。
评论
这取决于具体情况。
假设您有一些业务功能,并且需要进一步处理具有该值的内容,但在处理时具有该值会影响它。null
然后,在这种情况下,您可以使用 .Optional<?>
String nullName = null;
String name = Optional.ofNullable(nullName)
.map(<doSomething>)
.orElse("Default value in case of null");
b/w Optional.of 和 Optional.ofNullable 的主要区别在于,如果包装在 Optional 下的元素为 null,则 Optional.of 将引发 Null 指针异常,并停止进一步处理代码。而 Optional.ofNullable 将忽略 null 元素/对象并返回 Optional.empty() 或 NoSuchElementPresent。
这个问题已经有七年多的历史了,但我对最好的答案感到非常沮丧,以至于我不得不写下我的答案。
现有的答案,包括最好的答案,之所以不能正确回答问题,是因为原来的问题一开始就不合适。如果你没有设置正确的问题,你将不会得到正确的答案。
原始问题的不恰当之处在于它比较了错误的对。中有三种静态方法。java.util.Optional
Optional#empty()
Optional#of(T value)
Optional#ofNullable(T value)
该对不是 和 ,而是 和 。这是因为这两个是创建新实例的工厂方法,其中不提供公共构造函数。of
ofNullable
of
empty
Optional
您可以选择 和 何时要创建 的新实例。of
empty
Optional
Optional<Integer> answer = Optional.of(42); // or Optional.empty() if it's absent
在这种用法中,您确定不会传递给 ,因为是您自己在初始化实例。如果要创建一个空实例,则可以改为选择。因此,如果你在这个阶段传递一个值,这显然是一个错误,你应该收到一个NPE。null
of()
empty()
null
of()
这个问题的一位评论者建议,既然 比 更有用,不如命名为 和 。这个观点很好。但是,当您考虑到它是官方的工厂方法时,使用较短的名称定义更常用的方法是有道理的。此外,它也是一个好名字,与其他 Java 集合类工厂方法(如 、 和 )的命名一致。ofNullable
of
ofNullable
of
of
ofNotNull
of
empty
Optional
List#of()
Set#of()
Map#of()
那么什么是?这实际上是一种实用适配器方法,用于将 null 消除的世界与充满 s 的遗留世界联系起来。它用于包装在其他地方定义的变量,或从外部服务接收的返回值,以使它们对 null 安全。ofNullable
Optional
null
Optional
String foo = someExternalAPI();
Optional<String> bar = Optional.ofNullable(foo);
由于这是一种实用方法而不是主工厂方法,因此通常可以接受给它一个稍长的名称,甚至最好是实用程序方法具有一个描述性名称,以清楚地说明其意图。
总结
- 与 配对的是 .
Optional#of(T value)
Optional#empty()
- 使用 或 创建新实例。
of
empty
Optional
- 用于将现有变量包装为 .
ofNullable
Optional
评论
java.util.Optional
ofNullable()
of()
of()
ofNotNull()