Optional.get() versus overloaded Optional.orElseThrow()

Java 8 was a huge improvement to the platform, but one of the few mistakes we made was the naming of Optional.get(), because the name just invites people to call it without calling isPresent(), undermining the whole point of using Optional in the first place. (If this was the worst mistake we made in such a big release, then we did pretty well.)

During the Java 9 time frame, we proposed to deprecate Optional.get(), but the public response to that was ... let's say cold. As a smaller step, we introduced orElseThrow() in 10 (see https://bugs.openjdk.java.net/browse/JDK-8140281) as a more transparently named synonym for the current pernicious behavior of get(). IDEs warn on unconditional use of get(), but not on orElseThrow(), which is a step forward in teaching people to code better. The question is, in a sense, a "glass half empty" view of the current situation; get() is still problematic.

We'd love to improve the situation further in future version, but it will probably take some time to bring more of the community around.


An alternate method to get value of an optional instead of Optional.get (which more likely than not fails to keep up with user's expectations) is to replace it with a more verbose API introduced in JDK10 termed as Optional.orElseThrow(). In author's words -

Optional.get() is an "attractive nuisance" and is too tempting for programmers, leading to frequent errors. People don't expect a getter to throw an exception. A replacement API for Optional.get() with equivalent semantics should be added.

Optional<Integer> anyOddInStream = Stream.of(2, 4, 6, 8)
                                         .filter(x -> x % 2 == 1)
                                         .findAny();
// one could be well aware of the possible exception handling while reading this 
var current = anyOddInStream.orElseThrow(); 

Note :- The underlying implementation of both these APIs is same, yet the latter reads out more clearly that a NoSuchElementException would be thrown by default if the value is not present which inlines to the existing Optional.orElseThrow(Supplier<? extends X> exceptionSupplier) implementation used by consumers as an explicit alternative.


From my point of view, Optional.get() is the code smell. Very often combined with Optional.isPresent(), it completely defeats the purpose and the idea of Optional.get(). Here's a more complete reasoning and discussion:

http://royvanrijn.com/blog/2016/04/deprecating-optional-get/

So simply don't use Optional.get(). If you want to return null for the absent value, call Optional.orElse(null).