java.util.Objects vs Optional which is preferable?
The point is: those two method signatures are clearly different:
public static <T> T requireNonNullElse(T obj, T defaultObj)
vs.
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
The javadoc for the second method reads:
Returns the first argument if it is non-null and otherwise returns the non-null value of supplier.get().
In other words: it uses the supplier that you provide to it here.
So, the answer is: you use the second version for situations where you want to work with a supplier; and otherwise you simply take the "more simple" version of that method that takes the "less complicated" parameter.
The reasoning behind that: when you decide between two options, you prefer that one that is easier/"less reader surprising" to use. In other words: why would you want to provide a supplier, when you can go without.
Regarding the usage of Optionals - keep in mind that their main goal was to be used for return types; not as method parameters (see here for further reading).
Then: updating existing methods in a class delivered "to the field" is almost always a no-go. You absolutely do not want to change the semantics of something that is already out in the open and used by your customers; assuming specific semantics.
The shortest answer to your question "which is preferable?" is the all-time developer favorite "it depends" ð because Objects::requireNonNullElse
and Optional
cover different use cases.
The Two Alternatives
Before answering your questions I want to give some background on the two alternatives.
Objects::requireNonNullElse
Objects::requireNonNull
makes sure that the result of the call is never null (hence the name). It is usually used to succinctly verify constructor or method arguments and allows readers to verify with a glance that the variable to which the return value is assigned can not be null.
So it would not only be weird for Objects::requireNonNullElse
to suddenly allow null
, it would also be borderline useless because:
// if requireNonNullGet would allow null as second argument,
// the following is true for all x (including null)
Objects.requireNonNullElse(x, null) == x
You might argue that it is different for requireNonNullElseGet
because that might call a function that, depending on some state, might return null
or not. That's true and I assume it was considered but the requireNonNull...
API would be really weird if one of the three cases might actually allow the final result of the call to be null
even though the name says required non null.
Optional
Optional
was designed as a return argument in cases where returning null
is very likely to cause NPEs (like for a Stream
's terminal operation, where it was first used). Although some developers prefer to use it in more cases (compare Stephen Colebourne's pragmatic approach and my strict approach) no one really proposes using it as in your demonstration:
Optional.ofNullable(nullStr).orElse(null);
Optional.ofNullable(nullStr).orElseGet(() -> null);
Optional
is a way to express in the type system that something might be missing - it is not meant as an alternative to if
-null
-checks. In that sense orElse
or orElseGet
are backdoors out of Optional
back into the world of nullable types and sometimes null
is just what you want to use if something's not there, so it makes sense for them to accept null
as an argument (or the supplier's result).
Your Questions
Now we have what we need to answer your questions:
Why haven't the JDK developers updated existing methods in Optional class?
Conceptually that would go against what Optional
should be used for. But, as others have mentioned, this would be a backwards incompatible change as calls to orElse(null)
would suddenly throw exceptions.
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
APIs are only extended if considerable improvements of existing code can be expected. I don't see that here. In many cases orElse
gets an argument that the caller creates specifically as an alternative for empty optionals - there is rarely a need to make an extra check to verify it's not null
. If you really have to, call orElse(requireNonNull(x))
.
What should we use now Optional or Objects?
If you have a variable (be it local, an argument or a field) and you want to make sure it's not null, use Objects
. If you want to return something, which may be null consider wrapping it in Optional
. Be suspicious of code that creates an Optional
(as opposed to getting one form a call) and unwraps it at the end of the same chain.
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
As I'm sure is clear by now, they cover different use cases. But let me address "and not later on somewhere in the code like with Optional": Whatever you do, make sure to check your desired nullablity property (can be null
or not) in your code. Don't return something that you assume can not be null
but it turns out to be because you didn't check. If that happens, it's not Optional
's fault.
If I have a legacy code, something like:
String str = null; String result = str == null ? "other string" : str;
Definitely Objects.requireNonNullOrElse(str,"other string");
and consider using static imports to make it more readable.
Why haven't the JDK developers updated existing methods in Optional class?
Because that would introduce a breaking change that would break many existing programs, and because the method should allow getting null if desired.
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
Probably because that would make the API more convoluted and bloated for no significant advantage. You can still wrap the result with requireNonNull if you want to ensure your code doesn't return null unexpectedly.
What should we use now Optional or Objects?
If you need to extract a value out of an optional returned by a method, then use Optional's method. If you want to ensure preconditions are respected for the argument of a method that should not be null, use Object.requireXxx. The JDK designers have never advocated the use of Optional just to wrap a value and check for null. Optional is for return values.
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
See previous points: you don't use these methods to do the same thing.