Why use Optional.of over Optional.ofNullable?
Asked Answered
S

6

339

When using the Java 8 Optional class, there are two ways in which a value can be wrapped in an optional.

String foobar = <value or null>;
Optional.of(foobar);         // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException

I understand Optional.ofNullable is the only safe way of using Optional, but why does Optional.of exist at all? Why not just use Optional.ofNullable and be on the safe side at all times?

Squally answered 29/7, 2015 at 9:30 Comment(5)
please tell me which package must import to use this?Manpower
@Manpower java.util.Optional - It's available if you're using JDK 8 or laterSqually
I would love if they would have ofNullable() named of() and and of() named ofNotNull()Auschwitz
Please refer baeldung.com/java-optionalOlivine
As you are asking "why does Optional.of exist at all? Why not just use Optional.ofNullable and be on the safe side at all times?" Let's say if user's required data is not present, then we must throw exception. So, it totally depends on your usecase. baeldung.com/java-optional-throw-exceptionPrunelle
S
444

Your question is based on assumption that the code which may throw NullPointerException is worse than the code which may not. This assumption is wrong. If you expect that your foobar is never null due to the program logic, it's much better to use Optional.of(foobar) as you will see a NullPointerException which will indicate that your program has a bug. If you use Optional.ofNullable(foobar) and the foobar happens to be null due to the bug, then your program will silently continue working incorrectly, which may be a bigger disaster. This way an error may occur much later and it would be much harder to understand at which point it went wrong.

Santos answered 29/7, 2015 at 9:35 Comment(14)
"If you expect that your foobar is never null due to the program logic, it's much better to use Optional.of(foobar)". This seems a bit strange - when we know that the value won't be null in any case, then why not use the value itself, instead of wrapping it within an Optional ?Twin
@kocko, you may have to return the Optional from the method as required by interface you are implementing (probably other implementors may return an empty optional). Or you want to create a collection/stream of optionals, some of which are guaranteed non-null and some are not. Or you have conditional logic which creates an optional in several branches and in single branch you are sure that it's non-null.Santos
Because Optional means that it can be present, or absent. Absent != null. null in this case means "I expect foobar to be present, but due to a bug it is null". Optional.isPresent() == false means foobar is not present, ie this is expected, legitimate behaviour.Jeroboam
@kocko: simple example: return list.isEmpty()? Optional.empty(): Optional.of(list.get(0)); the list is expected to never contain null values…Orgeat
But wouldn't this make code cumbersome? If we practice of adding Optional.of() of ever method which I invoke outside my class (which I expect to return non null data), then the complete code base would just consist of Optional.of() tags everywhere?Hadhramaut
@Hadhramaut if you're asking me, I don't advise to use Optionals everywhere. That's a separate question. You may check some opinions here.Santos
@Holger: If why use the conditional operator to begin with (i.e return list.isEmpty() ? Optional.empty(): Optional.of(list.get(0)); )? Why not just return list.stream().findFirst();? Wouldn't that avoid the use of Optional.of(..)? :Duda
@Nawaz: you can use stream().findFirst() instead, because someone implemented it (using Optional.of(…)). It’s still an example use case, exemplary for any case where you have either, an absent value or a present, non-null value.Orgeat
@Holger: That is not the point, because a public method X could use many methods , that doesn't justify if they made them public too merely because they're used by the public method X. A public method is also meant to encourage good design in the users code; and so the question is, whether making the method .of() public encourages good design or not, in the user code? Did you get the argument now?Duda
@Nawaz: I already said, this one use case is exemplary for similar use cases where not a handy Stream API method exists to create the Optional behind the scenes. Is the existence of List.get(int) bad design, just because you could call stream().skip(index).findFirst() instead?Orgeat
I strongly disagree with this answer. If you already know that your variable cannot be null in a specific situation (and if it is you have a bug) what's the point in wrapping it with a Optional?Jenette
This answer does not make sense to me. If the intent of Optional.of() is to throw a NullPointerException and fail early, is using @NonNull, Validate.notNull, etc not a better choice? or even just doing a direct check: if (foobar != null) throw new NPE(). If the value of Optional is never going to be none then in this case is it not misleading to still call it an Optional?Stegosaur
@MarioFusco Because there might be multiple such specific situations in the same logic, and not all are present. eg, if (condition) { return Optional.of(f()); } else { Optional.empty(); }, where f() should never return null. Using ofNullable would hide errors when f does return null erroneously.Beaton
This is the worst answer. Java should check for null as part of "of" method.Toluidine
O
18

This question is over seven years old, but I felt so frustrated by the best answer that I had to write my answer.

The reason why the existing answers, including the best one, are failing to answer the question properly is because the original question is not appropriate in the first place. If you do not set the right question, you will not get the right answer.

What is improper about the original question is that it is comparing the wrong pair. There are three static methods in java.util.Optional.

  • Optional#empty()
  • Optional#of(T value)
  • Optional#ofNullable(T value)

The pair is not of and ofNullable, but of and empty. This is because these two are the factory methods that create new instances, where Optional doesn't provide a public constructor.

You can choose from of and empty when you want to create a new instance of Optional.

Optional<Integer> answer = Optional.of(42); // or Optional.empty() if it's absent

In this usage, you are sure you don't pass null to of(), because it is you who are initialising the instance. If you want to create an empty instance, you can just choose empty() instead. Therefore, if you are passing a null value to of() at this stage, it is obviously a bug and you should receive an NPE.

One of the commenters in this question suggested that, since ofNullable is more useful than of, it would have been better if ofNullable were named as of and of were ofNotNull. This opinion is well taken. However, when you consider that of and empty are the official Optional factory methods, it makes sense that the more commonly used one is defined with a shorter name. Furthermore, it is also a good name that is consistent with the naming of the other Java collection class factory methods such as List#of(), Set#of(), and Map#of().

So what is ofNullable? This one is actually a utility adapter method to bridge the null-eliminated Optional world with the legacy world full of nulls. It is used to wrap variables defined somewhere else, or return values received from external services, in Optional to make them null-safe.

String foo = someExternalAPI();
Optional<String> bar = Optional.ofNullable(foo);

As this is a utility method rather than a primary factory method, it should be generally acceptable to give it a slightly longer name, and it is even good practice that a utility method has a descriptive name which tells its intent clearly.

Summary

  • What is paired with Optional#of(T value) is Optional#empty().
  • Use of or empty to create a new Optional instance.
  • Use ofNullable to wrap an existing variable as Optional.
Obie answered 11/5, 2023 at 6:0 Comment(2)
This is so much clear. Thanks a lot. I was just scrolling down after the accepted answer because I was not satisfied. But now I dont have to scroll anymore.Combs
I think this should be the accepted answer. Well explained! :) ThanksBun
P
15

In addition, If you know your code should not work if object is null, you can throw exception by using Optional.orElseThrow

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .orElseThrow(NullPointerException::new);
                   // .orElseThrow(CustomException::new);
Prunelle answered 14/8, 2018 at 8:40 Comment(6)
But for this, you can use the even shorter String name = Objects.requireNonNull(nullName);Orgeat
Good point @Holger, however .orElse() method allows custom exceptions that might help you better handle flow of control or information logging.Semiautomatic
Well, you can supply a message for the exception to give additional information. Any other attempt of customization, like using a different exception than NullPointerException when the problem clearly is a reference that is null while it shouldn’t, would be a step into the wrong direction.Orgeat
also, you can use Optional to throw more specific (e.g. custom) Exception, not NPE, NPE is too generic, you can throw something like new NullNameException("meaningful msg")Trici
Isn't this exactly what Optional.of(value) does? Throw a NullPointerException if the value is null?Carbohydrate
@motobói You are right. Both methods do exactly the same. The use of Optional.get() is discouraged because it's a newbee trap. I think it is kept only for backward compatibility.Diastrophism
W
4

Main difference b/w Optional.of and Optional.ofNullable is that if the element wrapped under Optional is null, Optional.of will raise Null pointer exception and will stop further processing of code. whereas, Optional.ofNullable will just ignore null element/object and returns Optional.empty() or NoSuchElementPresent.

Weather answered 17/9, 2022 at 10:13 Comment(0)
I
2

This depends upon scenarios.

Let's say you have some business functionality and you need to process something with that value further but having null value at time of processing would impact it.

Then, in that case, you can use Optional<?>.

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .map(<doSomething>)
                      .orElse("Default value in case of null");
Incite answered 24/7, 2019 at 7:21 Comment(0)
A
0

Optional should mainly be used for results of Services anyway. In the service you know what you have at hand and return Optional.of(someValue) if you have a result and return Optional.empty() if you don't. In this case, someValue should never be null and still, you return an Optional.

Asymptote answered 11/9, 2018 at 10:58 Comment(1)
Thanks for the edit Sumesh, but the the "someValue" in the last line which you edited to be "some Value", references the variable in "Optional.of(someValue)" above and should stay someValue, i think.Asymptote

© 2022 - 2024 — McMap. All rights reserved.