RFR(m): 8140281 deprecate Optional.get()
Stuart Marks
stuart.marks at oracle.com
Thu Apr 28 02:49:43 UTC 2016
On 4/27/16 1:39 AM, Dr Heinz M. Kabutz wrote:
> thanks for these excellent examples of where Optional.get() is being used
> incorrectly in the JDK. I would like to publish a Java Specialists'
> Newsletter about this topic and hopefully educate at least a part of the Java
> proletariat on how to do it correctly. To my embarassment, this is the first
> time that I've /seen/ Optional.ifPresent(), so I include myself amongst the
> proles. I think it was just too close to Optional.isPresent() and I just
> overlooked it. However, the longer, clumsier name would not IMHO make any
> difference. I would rather ask the IDE vendors to build in autofix mechanisms
> to transform the code in these examples to what it should look like.
You're welcome. I'm also a bit embarrassed at finding this code in the JDK. I
guess we need to do some more internal education.
On the name, I'd be happy to find a less clumsy name that conveys the
programmer's assertion that a value is always present. I also think it's
reasonable, independently of any deprecation/renaming, for IDE vendors to add
rule checkers that attempt to detect unsafe uses of Optional. I'm a bit
skeptical of whether it's possible for there to be automatic fixes, but
detection would be a good step forward.
> Now a code style question. Let's say that I get back an Optional<BigInteger>
> and I currently do the following with it:
>
> Optional<BigInteger> prime = ...
> if (prime.isPresent()) {
> System.out.println("Prime is " + prime.get());
> } else {
> System.out.println("Prime not found");
> }
Assuming the Optional<BigInteger> came from a method called findPrime(), I'd
rewrite this code as follows:
System.out.println(findPrime().map(p -> "Prime is " + p)
.orElse("Prime not found"));
> Is there a better way of doing this? We'd almost need a
> ifPresentElse(Consumer<? super T> consumer, Runnable action) method I guess.
Close. In JDK 9 we added
ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
This is useful if you really need to perform separate actions in the different
cases, instead of just substituting or transforming values.
> Now, another question, do I have your permission to reference the examples of
> incorrect usage below and quote you on how it should be done in my newsletter?
Sure, I'd love to see your writeup on this. This is all open source and open
email logs, so there aren't any secrets here. There are a couple caveats though:
1) There are places in the JDK code where special conditions apply. For example,
early in startup, we avoid using lambdas because it drags in all the lambda
support code prematurely. In such cases my suggested changes wouldn't be
appropriate. I think this kind of issue doesn't apply to most applications and
libraries, though.
2) I don't claim to have the final word on the "right" way to use Optional. It
is, unfortunately, all too easy to find examples of poor usage of
Optional.get(). I've suggested some fixes that I like, but others might prefer
different approaches that are equally valid.
s'marks
More information about the core-libs-dev
mailing list