The java.util.Objects class was extended with a number of new methods
Objects#requireNonNullElse
respectively
Objects#requireNonNullElseGet() in Java-9
.
Both will return the first argument if it is non-null and otherwise returns the non-null second argument or the non-null value of supplier.get()
jshell> String nullStr = null;
nullStr ==> null
jshell> Objects.requireNonNullElse(nullStr,"lorem ipsum");
$13 ==> "lorem ipsum"
jshell> Objects.requireNonNullElseGet(nullStr,() -> "lorem ipsum");
$14 ==> "lorem ipsum"
But the new functionality overlaps with already existing in the Optional
class Optional#orElse and Optional#orElseGet
jshell> Optional.ofNullable(nullStr).orElse("lorem ipsum");
$17 ==> "lorem ipsum"
jshell> Optional.ofNullable(nullStr).orElseGet(() -> "lorem ipsum");
$18 ==> "lorem ipsum"
The only difference between new methods in Objects
and corresponding Optional
methods is that second argument or value of supplier must be non-null otherwise Objects
throws NPE
:
jshell> Objects.requireNonNullElseGet(nullStr,() -> null);
| java.lang.NullPointerException thrown: supplier.get()
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElseGet (Objects.java:321)
| at (#15:1)
jshell> Objects.requireNonNullElse(nullStr,null);
| java.lang.NullPointerException thrown: defaultObj
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElse (Objects.java:301)
| at (#16:1)
versus Optional
jshell> Optional.ofNullable(nullStr).orElse(null);
$19 ==> null
jshell> Optional.ofNullable(nullStr).orElseGet(() -> null);
$20 ==> null
If I have a legacy code, something like:
String str = null;
String result = str == null ? "other string" : str;
Which is just a simple check inside a method. And I would like to re-factor it using latest language features. Now having in mind the difference between Optional.orElse
and Objects.requireNonNullOrElse
which is preferable?
result = Optional.ofNullable(str).orElse("other string");
or
result = Objects.requireNonNullOrElse(str,"other string);
Optional is a new type introduced in Java 8. It is used to represent a value that may or may not be present. In other words, an Optional object can either contain a non-null value (in which case it is considered present) or it can contain no value at all (in which case it is considered empty).
In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.
Java 8 has introduced a new class Optional in java. util package. It is used to represent a value is present or absent. The main advantage of this new construct is that No more too many null checks and NullPointerException .
Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).
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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With