Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using Optional.ofNullable as a replacement for the ternary operator a good practice?

Consider the usage of this expression:

String hi = Optional.ofNullable(sayHi()).orElse("-");

which effectively corresponds to this ternary expression:

String hi = sayHi() != null ? sayHi() : "-";

Is this usage of Optional.ofNullable with a method call a good practice? Or just extra verbose coding?


I recognise that Optional.ofNullable actually creates a variable and avoids calling the sayHi() method twice. To avoid this problem you actually could create an extra variable but this adds to the verbosity of the ternary option:

String hi = sayHi();
hi = hi != null ? hi : "-";

On the other hand Optional.ofNullable creates in case of hi not being null an extra Optional object. So there is for sure more overhead to it.

So there seem to be some pros and cons to using this type of construct to replace the ternary constructor.


By the way: this is the Java 8 implementation of Optional.ofNullable:

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}
like image 369
gil.fernandes Avatar asked Nov 27 '18 16:11

gil.fernandes


People also ask

What is the use of optional ofNullable?

What is the ofNullable() method of the Optional class? The ofNullable() method is used to get an instance of the Optional class with a specified value. If the value is null , then an empty Optional object is returned.

Should I use optional or null?

A variable whose type is Optional should never itself be null ; it should always point to an Optional instance.”

Why is null better than optional?

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.

How do you replace an optional null check in Java 8?

With Java 8 Optional : UserObj userObj=new UserObj(); Optional. ofNullable(fetchDetails()). ifPresent(var -> userObj.


3 Answers

In JDK 9 or later, use this:

String hi = Objects.requireNonNullElse(sayHi(), "-");

This avoids having to repeat sayHi() if a ternary operator is used, or to assign its value to a local variable that is reused within the ternary. It might be a small improvement. It also sidesteps the question of whether to use Optional. :-)

like image 94
Stuart Marks Avatar answered Oct 19 '22 21:10

Stuart Marks


Whenever I come to think of using the Optional API for a specific purpose I always remind my self of what it was intended to do and why it was brought into the JDK and i.e.

Optional in intended to provide a limited mechanism for library method return types where there is a clear need to represent “no result” and where using null for this is overwhelmingly likely to cause errors - Stuart Marks

Optional is primarily focused on a return type that might or might not have a return value.

Over using this construct like in this specific example of yours just causes extra memory allocation and GC overhead.

I’d keep things simple and instead do:

String hi = sayHi();
if(hi == null) hi = “-“;
...
like image 40
Ousmane D. Avatar answered Oct 19 '22 20:10

Ousmane D.


Is this usage of Optional.ofNullable with a method call a good practice?

Conceptually, it's a bad practice. The basic idea is to represent the absence of a return value, not to wrap everything that might be null. I am strongly against this usage.

Or just extra verbose coding?

It looks to me like a failed attempt to make your code more fashionable. ("Look, we are using brand-new Optional from Java 8!")

I prefer readability and clarity over conciseness.

This Optinal usage doesn't provide clarity but raises questions:

Why do you wrap the variable?
What are you going to do with this Optional?
Will it be used/returned below?

It doesn't give brevity either: your second line is even shorter.

To avoid this problem you actually could create an extra variable but this adds to the verbosity of the ternary option.

You aren't creating an extra variable. The one-line version could be:

String hi = (hi = sayHi()) != null ? hi : "-";

Though, your two-line suggestion is absolutely fine:

String messageContent = sayHi();
String hi = messageContent != null ? messageContent : "-";
like image 28
Andrew Tobilko Avatar answered Oct 19 '22 20:10

Andrew Tobilko