Optional.Nullable()和`Optional.of()有什么区别



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

  • 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)of还是ofNullable的结果相同?

那么更确切地说of.orElseThrow更好吗?

来求和,最后,如果加上orElseThrow(nullPoint)of或Nullable是相同的结果吗?

否。要了解这一点,只需查看类型即可。

public static <T> Optional<T> of(T value);
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
throws X extends Throwable;

Optional.of返回一个Optional<T>,其中orElseThrow将给您留下一个CCD14。所以Optional.ofNullable(x).orElseThrow(...)实际上只是一个非常迂回的

if (x == null) {
throw new NullPointerException(...);
}

实际上,您并没有用Optional做任何事情,只是做了一个并以一种非常冗长的方式丢弃它。所以,如果这是你的意图,只需做一个明确的null检查;完全不需要CCD_ 18。

这就提出了我们为什么要使用ofofNullable的问题。随着Optional的引入,现在有两种方式来表示";该值可能不存在";在Java中:CCD_ 22和CCD_。互联网上的人会争论到底哪种更好,什么时候应该使用哪一种(我对此有强烈的意见,我不会在这里分享,因为这不是你要求的),但关键是有两种不同的方法。

在这篇文章的其余部分,我将借用Kotlin的一些符号,并将T?写成";可以是CCD_ 26"的CCD_;。这不是有效的Java表示法,但它能说明问题。因此,如果我们想代表";一个可能存在也可能不存在的CCD_;在Java中,我们可以使用Optional<T>T?

如果我们想从T?Optional<T>,那就是Optional.ofNullable的作用。上面写着";如果是null,给我Optional.empty();否则给我CCD_ 35"中的东西;。另一方面,我们可以使用Optional.orElse(null),它表示";如果我有一个T,把它给我,否则给我看null"。因此,现在我们有了在这两种方法之间转换的方法。那么Optional.of是干什么的呢?

您应该将Optional.of视为某种断言。如果Java有像Kotlin这样的可为null的类型,那么区别就有点像

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

也就是说,ofNullable期望其值可能是nullof已经假设它不是。Optional.of应该被认为是一个断言,即您给它的值不是null。如果断言失败,我们会立即抛出NullPointerException,而不是让错误传播到程序的其他部分。如果您正在调用Optional.of并从它抛出的NullPointerException中恢复,则表示您在做一些非常错误的事情。该函数是我们一开始处理非null数据的断言,如果该断言失败,那么您的程序应该立即失败,并进行良好的堆栈跟踪。

听起来,根据您的用例,您的值可能是null。在这种情况下,Optional.ofNullable是有意义的;它已准备好处理用例。如果您想抛出自定义异常,您应该事先进行null检查(因为您是处理null的人,而不是Optional的人),然后调用Optional.of。或者,当然,如果您计划使用orElseThrow提取Optional,您可以只进行老式的null检查,而根本不使用CCD_54。当然,一行中的管道Optional.ofNullable(value).orElseThrow(...)将是一种代码气味。


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

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

Optional.of:用于确保没有null,如果null为输入,nullPointExcepttion

Optional.ofNullable:可以是也可以不是null。用于响应灵活。

显然存在误解。

CCD_ 65的目的不是"em";以确保不存在CCD_。它并不是用来断言传递到它的值是非null。对于这样的验证,您可以使用Objects.requireNonNull(),它将抛出NPE,或者返回非null值

为了保持一致,您必须记住的第一件重要事情是,在JDK中引入选项只是为了一个特定的目的——用作返回类型。当可选用作参数类型或字段类型时,或者当可选对象存储在集合中时,任何其他情况都不被视为良好做法。此外,创建可选只是为了在其上链接方法或隐藏空检查,这被认为是反模式

以下是JDK:的开发者@StuartMarks的回答中的几句话

Optional的主要用途如下:

可选旨在为库方法返回类型提供有限的机制,其中显然需要表示";没有结果;以及其中使用null因为这极有可能导致错误。

一个典型的代码气味是,而不是使用方法链接到处理从某个方法返回的Optional,则从可为null的东西创建Optional,以便链接方法和避免条件语句

我还建议你看看这个问题的答案"是否应使用Optional.Nullable()进行null检查">,也由Stuart Marks撰写。

综上所述,Optional.of().orElseThrow()组合既错误又毫无意义:

  • 如果提供的数据是null,方法of()将引发NPE,并且orElseThrow()将不会执行(,即其异常将永远不会被激发)
  • 您通过创建一个可选对象来滥用可选,不是为了返回由其包装的可为null的变量而是为了隐藏null检查(请查看上面的引号)。这掩盖了代码的目的。如果给定值必须不是nullrequireNonNullElse()才能提供默认值,则可以使用Objects.requireNonNull()来引发异常

出于同样的原因,首先不应该使用Optional.ofNullable().orElseThrow()

可选就像一个盒子

您可能会认为是可选的,如果它是包裹。当你需要发送东西时,你会去邮局(,即从方法返回),在那里必须发送的东西被放入。当某人(,即呼叫者)收到包裹时,会立即将其拆包。这就是名为Optional的盒子的整个生命周期。

根据应用程序的逻辑,当需要从方法返回的对象不应该是null时,请使用Optional.of()。它要么会成功发送包裹,要么会通过提出NullPointerException来强调存在问题。

如果给定对象的性质为可为null,即null不是异常情况,则使用Optional.ofNullable(),它将激发包含该对象的框或空框。

调用方(即调用返回可选的方法的方法)是必须使用可选

最新更新