首先,我知道这两种方法之间的区别。
-
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。
这就提出了我们为什么要使用of
或ofNullable
的问题。随着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
期望其值可能是null
。of
已经假设它不是。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检查(请查看上面的引号)。这掩盖了代码的目的。如果给定值必须不是
null
或requireNonNullElse()
才能提供默认值,则可以使用Objects.requireNonNull()
来引发异常
出于同样的原因,首先不应该使用Optional.ofNullable().orElseThrow()
。
可选就像一个盒子
您可能会认为是可选的,如果它是包裹。当你需要发送东西时,你会去邮局(,即从方法返回),在那里必须发送的东西被放入框。当某人(,即呼叫者)收到包裹时,会立即将其拆包。这就是名为Optional
的盒子的整个生命周期。
根据应用程序的逻辑,当需要从方法返回的对象不应该是null
时,请使用Optional.of()
。它要么会成功发送包裹,要么会通过提出NullPointerException
来强调存在问题。
如果给定对象的性质为可为null,即null
不是异常情况,则使用Optional.ofNullable()
,它将激发包含该对象的框或空框。
调用方(即调用返回可选的方法的方法)是必须使用可选。