可选的nullable()和`可选的opational.of()有什么区别
首先我知道这两种方法的区别。
-
Optional.of
:用于保证不存在null,如果输入null,则为nullPointException -
Optional.ofNullable
:可能为 null,也可能不为 null。用于灵活应对。
那么,如果我添加 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
更好吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不。要看到这一点,只需查看类型即可。
Optional.of
返回一个Optional
,其中orElseThrow
将为您留下一个T
。所以Optional.ofNullable(x).orElseThrow(...)
实际上只是一个非常迂回的方法,您实际上并没有使用
Optional做任何事情>,只是制作一个并以一种非常冗长的方式丢弃它。因此,如果这是您的意图,只需执行显式
null
检查即可;根本不需要可选
。这就提出了一个问题:为什么我们要使用
of
或ofNullable
。随着Optional
的引入,现在Java中有两种方法来表示“这个值可能不存在”的概念:null
和Optional.empty()
。互联网上的人们会争论到底哪个更好,什么时候应该使用哪个(我对此有强烈的意见,我不会在这里分享,因为这不是你问的),但重点是有两种不同的方法可以做到这一点。在本文的其余部分,我将借用 Kotlin 的一些符号并编写
T?
来表示“一个可能为null”的
代码>”。这不是有效的 Java 表示法,但它表达了要点。因此,如果我们想在 Java 中表示“AT
值T
可能存在,也可能不存在”,我们可以使用Optional
或T?
。如果我们想从
T?
转到Optional
,这就是Optional.ofNullable
的用途。它说“如果该东西是null
,则给我Optional.empty()
;否则给我Optional
中的东西”。反之,我们可以使用Optional.orElse(null)
,它表示“如果我有一个T
,请将其给我,否则显示给我空
”。所以现在我们有一种方法可以在两种方法之间进行转换。那么Optional.of
有什么用呢?您应该将
Optional.of
视为某种断言。如果 Java 具有像 Kotlin 一样可为 null 的类型,那么差异将类似于That is,
ofNullable
期望其值可能为null
。of
已经假设事实并非如此。Optional.of
应该被认为是一个断言,即您给它的值不为空。如果该断言失败,我们会立即抛出 NullPointerException,而不是让错误传播到程序的其他部分。如果您调用Optional.of
并从抛出[1]的NullPointerException
中恢复,那么您正在做一些非常错误的事情。该函数是我们首先处理非空数据的断言,如果该断言失败,那么您的程序应该立即失败,并具有良好的堆栈跟踪。听起来,根据您的用例,您的值可能为
null
。在这种情况下,Optional.ofNullable 就有意义了;它已准备好处理用例。如果您想引发自定义异常,则应事先进行 null 检查(因为您是处理null
的人,而不是可选
),然后调用Optional.of
。或者,当然,如果您打算使用orElseThrow 来提取它,您可以只进行老式的
。当然,一行中的管道null
检查,根本不使用Optional
Optional.ofNullable(value).orElseThrow(...)
会产生代码味道。[1] 请注意,我说的是“从中恢复”,而不是“捕获”。记录所有错误的优秀顶级
catch (Exception exc)
是完全可以接受的,并且在大型应用程序中通常是一个好主意。但是如果你正在执行 catch (NullPointerException exc) { return 0; } 或类似的东西,那么您需要重新考虑应该使用哪种Optional
方法。No. To see this, simply look at the types.
Optional.of
returns anOptional<T>
, whereorElseThrow
is going to leave you with aT
. SoOptional.ofNullable(x).orElseThrow(...)
is really just a very roundaboutYou're not actually doing anything with the
Optional
, just making one and discarding it in a really verbose way. So if that's your intent, just do an explicitnull
check; there's no need at all forOptional
.Which raises the question of why we would use
of
orofNullable
. With the introduction ofOptional
, there are now two ways to represent the concept of "this value might not exist" in Java:null
andOptional.empty()
. People on the Internet will argue till the end of time about which is better and when you should use which one (I have strong opinions on this which I'll refrain from sharing here, since it's not what you asked), but the point is that there are two different ways to do it.For the rest of this post, I'll borrow a bit of notation from Kotlin and write
T?
to mean "aT
value which might benull
". It's not valid Java notation, but it gets the point across. So if we want to represent "AT
which may or may not exist" in Java, we can use eitherOptional<T>
orT?
.If we want to go from
T?
toOptional<T>
, that's whatOptional.ofNullable
is for. It says "If the thing isnull
, give meOptional.empty()
; otherwise give me the thing in anOptional
". To go the other way, we can useOptional.orElse(null)
, which says "If I have aT
, give it to me, otherwise show menull
". So now we have a way to convert between the two approaches. So what'sOptional.of
for?You should view
Optional.of
as an assertion of sorts. If Java had nullable types like Kotlin, then the difference would be something likeThat is,
ofNullable
expects that its value might benull
.of
is already assuming that it's not.Optional.of
should be thought of an assertion that the value you're giving it is not null. If that assertion fails, we throwNullPointerException
immediately rather than letting errors propagate to other parts of the program. If you're callingOptional.of
and recovering from theNullPointerException
it throws[1], then you are doing something very wrong. That function is an assertion we were dealing with non-null data to begin with, and if that assertion fails then your program should fail immediately with a good stack trace.It sounds like, based on your use case, you have a value that might be
null
. In that case,Optional.ofNullable
makes sense; it's prepared to handle the use case. If you want to throw a custom exception, you should do a null check beforehand (since you're the one handling thenull
, notOptional
) and then callOptional.of
. Or, of course, you can just do an old-fashionednull
check and not useOptional
at all, if you're planning to extract it anyway withorElseThrow
. Certainly, the pipelineOptional.ofNullable(value).orElseThrow(...)
in one line would be a code smell.[1] Note that I say "recovering from", not "catching". A nice top-level
catch (Exception exc)
which logs all errors is perfectly acceptable and generally a good idea in larger applications. But if you're doingcatch (NullPointerException exc) { return 0; }
or something like that then you need to reconsider whichOptional
method you should be using.有一个明显的误解。
Optional.of()
的目的不是“确保不存在null
”。它并不意味着用作传递给它的值是非空的断言。对于这样的验证,您可以使用Objects.requireNonNull()
,它要么抛出一个 NPE,要么返回一个 non-无效的值。。为了达成共识,您必须牢记的第一件重要事情是,JDK 中引入可选选项仅用于一个特定目的 - 充当返回类型。当可选用作参数类型或字段类型,或者可选对象存储在集合中时,任何其他情况都不被认为是一个好的做法。同样,创建一个可选只是为了在其上链接方法或隐藏空检查,被认为是反模式。
以下是 JDK 开发者 @StuartMarks 的回答中的几句话:
我还建议您看看这个问题的答案 “ShouldOptional.ofNullable() 用于空检查吗? “,同样由斯图尔特·马克斯创作。
话虽如此,组合
Optional.of().orElseThrow()
既错误又毫无意义:null
方法of() 将引发 NPE 并且
orElseThrow()
将不会被执行(即它的异常永远不会被触发)。null
或requireNonNullElse()
来提供默认值,您可以使用Objects.requireNonNull()
来引发异常价值。出于同样的原因,您不应该首先使用
Optional.ofNullable().orElseThrow()
。可选就像一个盒子
您可能会认为可选是它是包裹。当您需要发送某些内容时,您会前往邮局(即从该方法返回),需要发送的内容将被放入一个 >框。当某人(即呼叫者)收到包裹时,它会立即被拆包。这就是名为
Optional
的盒子的整个生命周期。根据应用程序的逻辑,当需要从方法返回的对象不应为
null
时 - 使用Optional.of()
。它要么成功发送包裹,要么通过引发 NullPointerException 来强调存在问题。如果给定对象本质上可以为空,即
null
不是异常情况,那么使用Optional.ofNullable()
,它'将发射一个包含该物体的盒子或一个空盒子。调用者(即调用返回可选值的方法的方法)必须使用各种工具来打开盒子 可选提供诸如
orElseThrow()
、orElseGet()
、ifPresent()
等。There's a clear point of misunderstanding.
The purpose of
Optional.of()
is not "to ensure that there is nonull
". It is not meant to be used as an assertion that a value that was passed into it is non-null. For such a validation you can useObjects.requireNonNull()
, it'll either throw an NPE, or will return you a non-null value.In order to be on the same page, the first important thing you have to keep in mind is that optionals were introduced in the JDK for only one particular purpose - to serve as a return type. Any other cases when optional is utilized as a parameter-type, or a field-type, or when optional objects are being stored in a collection isn't considered to be a good practice. As well, as creating an optional just in order to chain methods on it or to hide a null-check is considered to be an antipattern.
Here is a couple of quotes from the answer by @StuartMarks, developer of the JDK:
I also suggest you to have a look at this answer to the question "Should Optional.ofNullable() be used for null check?", also by Stuart Marks.
With all that being said, combination
Optional.of().orElseThrow()
is both wrong and pointless:null
methodof()
will raise an NPE andorElseThrow()
will not be executed (i.e. its exception will get never be fired).Objects.requireNonNull()
instead to throw an exception if the given value must not benull
orrequireNonNullElse()
to provide a default value.For the same reason, you shouldn't use
Optional.ofNullable().orElseThrow()
at the first place.Optional is like a Box
You might think of optional is if it is a parcel. When you need to send something, you go to the post office (i.e. returning from the method), where the thing that has to be sent is being placed into a box. When somebody (i.e. the caller) receives the parcel, it is being immediately unpacked. That is the whole lifecycle of the box called
Optional
.When, according to the logic of your application, an object required to be returned from the method should not be
null
- useOptional.of()
. It'll either send a parcel successfully or will emphasize that there's a problem by raising aNullPointerException
.If the given object is nullable by its nature, i.e.
null
isn't an abnormal case, then useOptional.ofNullable()
, it'll fire either a box containing the object or an empty box.And the caller (i.e. method that invokes the method returning an optional) is the one who has to unpack the box using a variety of tools that optional provides like
orElseThrow()
,orElseGet()
,ifPresent()
, etc.