First of all, I know the difference between the two methods.
Optional.of
: Used to ensure that there is no null, if null is entered, nullPointExcepctionOptional.ofNullable
: may or may not be null. Used to respond flexibly.
So, if I add orElseThrow(() -> new NullPointerException("null data"))
to this, will it end up being the same?
I want to throw an error with explicit content.
So I get Optional.ofNullable(data).orElseThrow(() -> new NullPointerException("null data")))
use it as Is this pointless behaviour?
Optional.of(data).orElseThrow(() -> new NullPointerException("null data")))
I think this is also possible, but I'm just using ofNullable()
to make the code look consistent.
to sum it up,
In the end, if you add orElseThrow(nullPoint)
Are of
or ofNullable
the same result?
then rather
Is of.orElseThrow
better?
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.