Optional.ofNullable() 和 `Optional.of() 之间有什么区别

바보린*_*바보린 4 java nullable java-8 null-check option-type

首先我知道这两种方法的区别。

  • Optional.of:用于保证不存在null,如果输入null,则nullPointException

  • Optional.ofNullable: 可能为空,也可能不为空。用来灵活应对。

那么,如果我加上orElseThrow(() -> new NullPointerException("null data"))这个,结果会是一样的吗?

我想抛出带有显式内容的错误。

所以我得到Optional.ofNullable(data).orElseThrow(() -> new NullPointerException("null data")))

将其用作这是无意义的行为吗?

Optional.of(data).orElseThrow(() -> new NullPointerException("null data")))

我认为这也是可能的,但我只是用来ofNullable()使代码看起来一致。

总结一下,到底如果加上的话结果还是一样orElseThrow(nullPoint)ofofNullable

那么反而of.orElseThrow更好呢?

Sil*_*olo 11

总结一下,到底如果加上 orElseThrow(nullPoint) of 或 ofNullable 结果是一样的吗?

不。要看到这一点,只需查看类型即可。

public static <T> Optional<T> of(T value);

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
                               throws X extends Throwable;
Run Code Online (Sandbox Code Playgroud)

Optional.of返回一个Optional<T>,哪里orElseThrow会给你留下一个T。所以Optional.ofNullable(x).orElseThrow(...)真的只是一个非常迂回的地方

if (x == null) {
  throw new NullPointerException(...);
}
Run Code Online (Sandbox Code Playgroud)

您实际上并没有对 做任何事情Optional,只是创建一个并以一种非常冗长的方式丢弃它。因此,如果这是您的意图,请进行明确的null检查;根本没有必要Optional

of这就提出了我们为什么要使用or的问题ofNullable。随着 的引入Optional,Java 中现在有两种方式来表示“这个值可能不存在”的概念:nullOptional.empty()。互联网上的人们会争论到底哪个更好,什么时候应该使用哪个(我对此有强烈的意见,我不会在这里分享,因为这不是你问的),但重点是有两种不同的方法可以做到这一点。

在这篇文章的其余部分,我将借用 Kotlin 的一些符号并写T?为“T可能是null”的值。这不是有效的 Java 表示法,但它表达了要点。因此,如果我们想T在 Java 中表示“A 可能存在,也可能不存在”,我们可以使用Optional<T>T?

如果我们想从T?Optional<T>,这就是Optional.ofNullable目的。它说“如果是null,给我Optional.empty();否则,给我这个东西Optional”。反之,我们可以使用Optional.orElse(null),它表示“如果我有一个T,请将其给我,否则显示给我null”。所以现在我们有一种方法可以在两种方法之间进行转换。那么有什么Optional.of用呢?

您应该将其视为Optional.of某种断言。如果 Java 像 Kotlin 一样具有可空类型,那么区别将类似于

public static <T> Optional<T> of(T value);
public static <T> Optional<T> ofNullable(T? value);
Run Code Online (Sandbox Code Playgroud)

也就是说,ofNullable预计其值可能是nullof已经假设事实并非如此。Optional.of应该被认为是一个断言,即您赋予它的值不为空。如果该断言失败,我们会NullPointerException立即抛出异常,而不是让错误传播到程序的其他部分。如果您正在调用并从它抛出的[1]Optional.of中恢复,那么您正在做一些非常错误的事情。该函数是我们首先处理非空数据的断言,如果该断言失败,那么您的程序应该立即失败,并具有良好的堆栈跟踪。NullPointerException

听起来,根据您的用例,您的值可能是null. 在这种情况下,Optional.ofNullable这是有道理的;它已准备好处理用例。如果您想引发自定义异常,您应该事先进行空检查(因为您是处理null, not 的人Optional),然后调用Optional.of. 或者,当然,如果您打算null使用. 当然,一行中的管道会产生代码味道。OptionalorElseThrowOptional.ofNullable(value).orElseThrow(...)


[1]请注意,我说的是“恢复”,而不是“捕获”。catch (Exception exc)记录所有错误的良好顶级是完全可以接受的,并且在大型应用程序中通常是一个好主意。但如果您正在catch (NullPointerException exc) { return 0; }这样做或类似的事情,那么您需要重新考虑Optional应该使用哪种方法。

  • “如果 Java 有可为 null 的类型”,我们可能根本就不需要 `Optional`。顺便说一句,`if (x == null) { throw new NullPointerException(message); 的惯用替代方案是:}` 是 [`Objects.requireNonNull(x, message);`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Objects.html #requireNonNull(T,java.lang.String)) (2认同)