为啥使用 Optional.of 而不是 Optional.ofNullable?
Posted
技术标签:
【中文标题】为啥使用 Optional.of 而不是 Optional.ofNullable?【英文标题】:Why use Optional.of over Optional.ofNullable?为什么使用 Optional.of 而不是 Optional.ofNullable? 【发布时间】:2015-10-20 04:48:01 【问题描述】:使用 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
并始终保持安全?
【问题讨论】:
请告诉我必须导入哪个包才能使用它? @LoveToCodejava.util.Optional
- 如果您使用的是 JDK 8 或更高版本,则可用
如果他们将ofNullable()
命名为of()
和of()
命名为ofNotNull()
,我会很高兴
请参考baeldung.com/java-optional
当您问“为什么 Optional.of 存在?为什么不直接使用 Optional.ofNullable 并始终保持安全?”假设如果用户所需的数据不存在,那么我们必须抛出异常。因此,这完全取决于您的用例。 baeldung.com/java-optional-throw-exception
【参考方案1】:
您的问题是基于这样的假设,即可能抛出NullPointerException
的代码比可能不会抛出的代码更糟糕。这个假设是错误的。如果您希望您的foobar
由于程序逻辑而永远不会为空,那么使用Optional.of(foobar)
会更好,因为您会看到NullPointerException
这将表明您的程序有错误。如果你使用Optional.ofNullable(foobar)
而foobar
恰好是null
由于该错误,那么你的程序将默默地继续不正确地工作,这可能是一个更大的灾难。这样一来,错误可能会在很久以后才发生,并且更难理解它是在什么时候出错的。
【讨论】:
"如果您希望 foobar 由于程序逻辑而永远不会为空,则最好使用Optional.of(foobar)
"。这似乎有点奇怪 - 当我们知道值不会是 null
在任何情况下,那么为什么不使用值本身,而不是将其包装在 Optional
中?
@kocko,您可能必须根据您正在实现的接口的要求从方法中返回Optional
(可能其他实现者可能会返回一个空的可选项)。或者你想创建一个可选的集合/流,其中一些保证非空,而有些则不是。或者你有条件逻辑,它在多个分支中创建一个可选的,在单个分支中你确定它是非空的。
因为可选意味着它可以存在或不存在。缺席!= null。 null
在这种情况下意味着“我希望 foobar 存在,但由于错误它为空”。 Optional.isPresent() == false
表示 foobar 不存在,即这是预期的合法行为。
@kocko:简单示例:return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));
list
预计永远不会包含 null
值...
@Harish 如果你问我,我不建议在任何地方使用 Optionals。那是一个单独的问题。您可以查看一些意见here。【参考方案2】:
另外,如果你知道你的代码在 object 为 null 时不应该工作,你可以使用 Optional.orElseThrow
String nullName = null;
String name = Optional.ofNullable(nullName)
.orElseThrow(NullPointerException::new);
// .orElseThrow(CustomException::new);
【讨论】:
但是为此,您可以使用更短的String name = Objects.requireNonNull(nullName);
好点 @Holger,但是 .orElse() 方法允许自定义异常,这可能有助于您更好地处理控制流或信息记录。
好吧,您可以为异常提供一条消息以提供更多信息。任何其他自定义尝试,例如使用与NullPointerException
不同的异常,当问题显然是null
的引用而它不应该时,将是朝着错误方向迈出的一步。
另外,您可以使用 Optional 来抛出更具体的(例如自定义)异常,而不是 NPE,NPE 太通用,您可以抛出类似 new NullNameException("meaningful msg")
这不正是 Optional.of(value) 的作用吗?如果值为 null,则抛出 NullPointerException?【参考方案3】:
这取决于场景。
假设您有一些业务功能,并且您需要进一步处理具有该值的东西,但在处理时具有 null
值会影响它。
那么,在这种情况下,您可以使用Optional<?>
。
String nullName = null;
String name = Optional.ofNullable(nullName)
.map(<doSomething>)
.orElse("Default value in case of null");
【讨论】:
【参考方案4】:无论如何,Optional 应该主要用于服务的结果。在服务中,您知道您手头有什么,如果有结果则返回 Optional.of(someValue) ,如果没有则返回 Optional.empty()。在这种情况下, someValue 永远不应该为 null 并且仍然返回一个 Optional。
【讨论】:
感谢 Sumesh 的编辑,但您编辑为“某个值”的最后一行中的“someValue”引用了上面“Optional.of(someValue)”中的变量,应该保留一些价值,我想。以上是关于为啥使用 Optional.of 而不是 Optional.ofNullable?的主要内容,如果未能解决你的问题,请参考以下文章
如果我们将Optional.of方法设为私有,并且只允许Java中的Optional.ofNullable,该怎么办?除了向后兼容性会有什么问题吗?