RFR(s): 8140281 add no-arg Optional.orElseThrow() as preferred alternative to get() (original) (raw)

Tagir Valeev amaembo at gmail.com
Mon Dec 18 10:31:47 UTC 2017


Hello!

I think that both methods could co-exist with slightly different semantics (even though they implementation is identical):

The get() method should be called when it's evident from the narrow context that Optional is present at the point and using functional alternatives (like ifPresent()) is inconvenient at this place, e.g.:

for(X x : list) { Y y = calculateYPossiblyThrowingCheckedException(x); Optional optional = getOptional(x, y); if(optional.isPresent()) { return optional.get(); // get() will always succeed } } return null; // or whatever else default value

Such loop is difficult to convert to Stream/Optional chain and not very easy to get rid of isPresent/get. One possibility is to change to T t = getOptional(x, y).orElse(null); if(t != null) return t; But it's really questionable (after all using optionals we want to get rid of nulls). So I think having get() here is fine. Think of get() as an assertion-like method: if get() throws, then it's a bug in the code (most likely right in this method).

The orElseThrow() method should be called when we are not sure that Optional is present (e.g. it's received from the method call), but we are fine with default NoSuchElementException. If orElseThrow() throws, then it's an acceptable situation (e.g. we are inside the library method and it documents that NoSuchElementException could be thrown if some precondition is not met).

In IntelliJ IDEA we warn by default if get() is called and we cannot statically determine that Optional is always present at this point (e.g. isPresent() was checked). In future Java we may suggest to replace with orElseThrow() in such cases. However I don't like issuing a warning if get() is used like in the code above. And if get() will be deprecated, then we would need to issue warning on every get() usage. Thus I'm against the deprecation.

I know that you like get() (or at least you're OK with it). But even three years after the release of Java 8, I still see bad code written with get(), so I don't think this problem is going to go away.

I believe that for any kind of API you can find bad code which abuses it regardless on how many years passed since the API was released. That's not always the fault of API creators.

With best regards, Tagir Valeev.



More information about the core-libs-dev mailing list