297

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?

Andrew Tobilko
  • 46,063
  • 13
  • 87
  • 137
whirlwin
  • 15,222
  • 17
  • 67
  • 96
  • 1
    please tell me which package must import to use this? – LoveToCode Oct 05 '16 at 11:25
  • 5
    @LoveToCode `java.util.Optional` - It's available if you're using JDK 8 or later – whirlwin Oct 05 '16 at 13:44
  • 31
    I would love if they would have `ofNullable()` named `of()` and and `of()` named `ofNotNull()` – Robert Niestroj Jun 13 '18 at 12:10
  • Please refer https://www.baeldung.com/java-optional – Sumesh TG Sep 11 '18 at 11:12
  • 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. https://www.baeldung.com/java-optional-throw-exception – Karan Arora May 20 '19 at 20:46

4 Answers4

398

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.

Tagir Valeev
  • 92,683
  • 18
  • 210
  • 320
  • 177
    "*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` ? – Konstantin Yovkov Jul 29 '15 at 09:38
  • 62
    @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. – Tagir Valeev Jul 29 '15 at 09:40
  • 30
    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. – Buurman Jul 29 '15 at 09:42
  • 45
    @kocko: simple example: `return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));` the `list` is expected to never contain `null` values… – Holger Jul 29 '15 at 14:04
  • 2
    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? – Harish May 04 '16 at 03:12
  • 5
    @Harish if you're asking me, I don't advise to use Optionals everywhere. That's a separate question. You may check some opinions [here](http://stackoverflow.com/q/23454952/4856258). – Tagir Valeev May 04 '16 at 03:54
  • 2
    @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(..)`? : – Nawaz Aug 04 '17 at 20:30
  • @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. – Holger Aug 06 '17 at 14:18
  • @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? – Nawaz Aug 06 '17 at 14:39
  • @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? – Holger Aug 06 '17 at 14:47
  • 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? – Mario Fusco Feb 24 '20 at 08:47
  • 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? – Vikram Singh Jun 14 '20 at 10:44
14

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);
Karan Arora
  • 158
  • 1
  • 6
  • 6
    But for this, you can use the even shorter `String name = Objects.requireNonNull(nullName);` – Holger Feb 13 '19 at 08:42
  • 2
    Good point @Holger, however .orElse() method allows custom exceptions that might help you better handle flow of control or information logging. – Nikos Stais Nov 17 '19 at 07:22
  • 4
    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. – Holger Nov 18 '19 at 09:11
  • 1
    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")` – Dáve May 29 '20 at 07:04
  • 1
    Isn't this exactly what Optional.of(value) does? Throw a NullPointerException if the value is null? – motobói Jun 24 '21 at 13:35
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");
blurfus
  • 12,450
  • 7
  • 53
  • 58
Gautam
  • 29
  • 1
  • 4
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.

KrishPrabakar
  • 2,694
  • 2
  • 28
  • 43
  • 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. – espendennis Sep 13 '18 at 11:04