So, if you would permit the pun, Oracle issued an oracle:
Thou shalt not use
Optional
but for function return values.
Ηere is a dissenting opinion:
You can completely eliminate
null
from your code base by usingOptional
everywhere: not only in function return values, but also in function parameters, in class members, in array members, even in local variables.
I have done it in a 100k-lines-of-code project. It worked.
If you decide to go along this path, then you will need to be thorough, so you will have a lot of work to do. The example mentioned in the accepted answer with Optional.ofNulable()
should never occur, because if you are thorough, then you should not have null
anywhere, and therefore no need for Optional.ofNullable()
.
In that 100k-lines-of-code project that I mentioned above, I have only used Optional.ofNullable()
a couple of times when receiving results from external methods that I have no control over. I have never had to pass Optional.ofNullable( nullablePointer )
as a parameter to a function because I do not have any nullable pointers lying around: I always convert them to optionals at the few places where they enter my system.
Now, if you decide to go along this path, your solution will not be the most performant solution possible, because you will be allocating lots of instances of Optional
. However:
- It is nothing but a runtime performance disadvantage.
- Although the disadvantage is non-negligible, it is also not severe.
- It is Java's problem, not your problem.
Let me explain that last bit.
Java does not offer explicit nullability of reference types as C# does (since version 8.0) so it is inferior in this regard. (I said "in this regard"; in other regards, Java is better; but that's off-topic right now.)
The only proper alternative to explicit nullability of reference types is the Optional
type. (And it is arguably even slightly better, because with Optional
you can indicate optional-of-optional if you must, whereas with explicit nullability you cannot have ReferenceType??
, or at least you cannot in C# as it is currently implemented.)
Optional
does not have to add overhead, it only does so in Java. That's because Java also does not support true value types, as C# and Scala do. In this regard, Java is severely inferior to those languages. (Again, I said "in this regard"; in other regards, Java is better; but that's off-topic right now.) If Java did support true value types, then Optional
would have been implemented as a single machine word, which would mean that the runtime overhead of using it would be zero.
So, the question that it ultimately boils down to is:
Do you want perfect clarity and type safety in your code, or do you prefer maximum performance?
I believe that for high-level languages, (of which Java certainly aims to be one,) this question was settled a long time ago.