Objects.requireNonNullElse()和Optional.ofNullable().orElse()有何不同?

20

Java 9 引入了 Objects 类中的 requireNonNullElserequireNonNullElseGet 方法。这些方法在功能上与 Optional.ofNullable()orElse()orElseGet() 方法有什么不同吗?

String foo = null;
Objects.requireNonNullElse(foo, "nonNull");//returns the string "nonNull"
Optional.ofNullable(foo).orElse("nonNull");//also returns the string "nonNull"

如果它们没有功能上的差异,那么为什么现在添加了Objects

2个回答

27

它们的行为有一个小差别。Objects.requireNonNullElse() 要求其中一个参数不为null,否则会抛出 NullPointerException

String foo = null, bar = null;
Optional.ofNullable(foo).orElse(bar); //returns a null value
Objects.requireNonNullElse(foo, bar); //throws a NullPointerException

4
还有一个微不足道的非功能性差别,即“Optional”版本会生成垃圾(除非JIT足够聪明以将其优化掉)。 - Andreas
3
@Andreas JMH 报告说,Optional.ofNullable().orElse()Objects.requireNonNullElse() 之间在分配方面没有区别。 - ZhekaKozlov
@ZhekaKozlov 只有当 foonull 时,ofNullable() 才会返回常量 empty 实例。你试过用非空的 foo 进行 JMH 测试吗?因为我认为这个问题是在问两者之间的函数差异是什么,对于 任何 值,而不仅仅是 null 值。 - Andreas
1
@Andreas 是的,我使用了非空的 foo 。当该方法处于热状态时,分配速率将降至零。 - ZhekaKozlov

4
选择一个而不是另一个的概念差异在于它们的文档中所解释的。这取决于API使用者的方法来选择哪一个对他们有效地使用。
Optional 是一个容器对象,可能包含或不包含非空值。

类型为 Optional 的变量本身不应为 null;它应该始终指向一个 Optional 实例。

这是一个基于值的类;对 Optional 实例进行身份敏感操作(包括引用相等性(==)、标识哈希码或同步)可能会产生不可预测的结果,应避免使用。

  • ofNullable

    如果指定的值非空,则返回带有当前值的Optional,否则返回一个空的Optional

  • orElse

    如果存在值则返回该值,否则返回其他值

因此,以下是行为:

String foo = null;
=> Optional.ofNullable(foo).orElse("nonNull")
=> Optional.ofNullable(null).orElse("nonNull")
=> Optional.empty().orElse("nonNull")
=> return otherwise "nonNull"

同样遍历它

String foo = null, bar = null;
=> Optional.ofNullable(foo).orElse(bar);
=> Optional.ofNullable(null).orElse(bar);
=> Optional.empty().orElse(bar)
=> return otherwise 'bar'
=> returns null

Objects是一个类,由静态实用方法组成,用于操作对象或在操作之前检查某些条件。

这些实用程序包括对空值安全或容忍空值的方法,用于计算对象的哈希码、返回对象的字符串、比较两个对象以及检查索引或子范围值是否越界。

  • requireNonNullElse

    如果第一个参数非空,则返回第一个参数,否则返回第二个参数(如果它非空)

因此,行为上的差异在于:

String foo = null;
=> Objects.requireNonNullElse(foo, "nonNull")
=> Objects.requireNonNullElse(null, "nonNull");

这进一步在内部评估是否 requireNonNull("nonNull", "defaultObj"),然后

=> returns "nonNull" since its a non-null value

现在它遍历
String foo = null, bar = null;
=> Objects.requireNonNullElse(foo, bar);
=> Objects.requireNonNullElse(null, bar);

它内部会检查 requireNonNull(bar, "defaultObj"),然后...
=> throws a NullPointerException

正如所记录的那样

throws NullPointerException - 如果 obj 和 defaultObj 都为 null


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接