Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to use Optional.ofNullable for checking if null and assigning default value

My code reads some configuration values from DB. In case they are undefined (returned null by getValueFromDB method) I want to default them to values defined in config file.

Is it ok to use Optional.ofNullable().OrElse() for all occurrences of getValueFromDB() to do null check and assign default value in case of null. Or will this be a misuse/abuse of Optional ?

like image 866
Andy897 Avatar asked Nov 24 '17 05:11

Andy897


People also ask

Why we use Optional instead of null check?

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.

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.

How do you use Optional instead of null check?

Optional was introduced to Java as a way to fix the issues with null references. Before Optional , every object was allowed to either contain a value or not (i.e. being null ). The introduction of Optional essentially enforces null -checking by the type-system making it unnecessary to perform such checks manually.

Can Optional have null value?

Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as 'available' or 'not available' instead of checking null values. It is introduced in Java 8 and is similar to what Optional is in Guava.


3 Answers

Well, we use this idiom in our code base like crazy - I see no problem what-so-ever with it. This is what Optional is all about to me - forcing you to take an action if some value is present or not; what I absolutely love is that it is build in the language itself as of java-8 and I don't have to introduce additional methods for that (or libraries like guava).

You might be thinking for this simple case here, but Optional has other chained method as-well obviously, so I can do:

Optional.ofNullalbe(dbPass)
        .map(// do mapping)
        .filter(// do filtering)
        .ifPresent(x -> // log it )

You can't easily achieve that with other methods.

like image 140
Eugene Avatar answered Oct 19 '22 01:10

Eugene


It seems like a small abuse, but I don't feel strongly about it. Maybe if enough programmers start doing this, it will become an accepted idiom.

But you can do the same thing without using Optional:

public static <T> T useValueOrDefault(T value, T defaultValue) {
    return (value == null) ? defaultValue : value;
}

and use this method everywhere instead of Optional.ofNullable(value).orElse(default). (Note: not tested)

I do find that built-in constructs that accomplish this, like || in Javascript or ?: in Kotlin, are useful. Too bad Java doesn't have an equivalent (EDIT: according to @Holger's comment, Java 9 has introduced one).

like image 39
ajb Avatar answered Oct 19 '22 00:10

ajb


It feels excessively ornate to convert something to an Optional only to immediately convert it back to the wrapped type using orElse in the same method.

To me Optional is more about exposing the possibility that a returned value might be empty, in a method's type signature. The Optional type communicates to the consumer that it might be empty. If you created it with ofNullable on the previous line of code, you are both the creator and the consumer, and already know that it might be null -- so deal with it in-place without creating a new short-lived object.


However, Optional fosters tidy code, and my first instinct is to ask whether your database API has the ability to return Optional.empty() instead of null, itself. This depends on the library you're using, and is possibly more likely in 2020 than it was when you asked the question in 2017.

In that case it would make perfect sense to use returnedOptional.orElse(default) if that's the application logic.


If your database API can't give you an Optional, I wouldn't, in the application logic, go via Optional to do the defaulting. It's simpler and clearer to use:

return value == null ? default : value;

However I would consider adding a thin abstraction layer between your Optional-incapable database API and your application logic, that just does Optional.ofNullable() where appropriate. Their DB library doesn't have the API you want, so wrap it to create the API you want. Your DB library has the courtesy to the caller, that when a value might be absent, the type signature says so.

So instead of:

MyType maybeS = theirDbLibrary.query(...);
MyType s = (maybeS == null) ? default : maybeS;

You'd have:

Optional<MyType> maybeS = myWrappedDbLibrary.query(...);
MyType s = maybeS.orElse(default);

The intent here is to remove all knowledge of null from your application logic. If the core of your application has no reference to null at all (including ofNullable), that's really great. It removes lots and lots of opportunities for bugs. But for that to be possible you need to eliminate the possibility that a null gets passed into your code -- and that's where your clean-up layer between the DB and your application code does its work.

like image 22
slim Avatar answered Oct 19 '22 02:10

slim