RFR(m): 8140281 deprecate Optional.get()

Andrej Golovnin andrej.golovnin at gmail.com
Fri Apr 29 09:23:14 UTC 2016


Hi Stuart,

> 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.

IntelliJ IDEA already warns you when you use Optional.get()
without Optional.isPresent(). Just use the right IDE! ;-)

I understand that you must use Optional.get() in the bootstrap code of
Java Runtime to avoid usage of lambdas. But in the most other cases
(I would say in 99.9%) you don't need the #get() method at all. At this place
I would like to quote the user raimille1 from the discussion
https://news.ycombinator.com/item?id=11588927 about your change:

"There are many Java 8 developers using streams() and optionals
with an imperative programming mindset still."

And here is an example from JDK. Take look at the code
http://cr.openjdk.java.net/~smarks/reviews/8140281/webrev.0.jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java-.html
:

 397         cf.modules().forEach(m -> {
 398             ModuleReference mref = m.reference();
 399             map.put(mref.descriptor().name(), mref);
 400         });
 401
 402         // set of modules that are observable
 403         Set<ModuleReference> mrefs = new HashSet<>(map.values());
 404
 405         // add the other modules
 406         for (String mod : otherMods) {
 407             Optional<ModuleReference> omref = finder.find(mod);
 408             if (omref.isPresent()) {
 409                 ModuleReference mref = omref.get();
 410                 map.putIfAbsent(mod, mref);
 411                 mrefs.add(mref);
 412             } else {
 413                 // no need to fail
 414             }
 415         }

It is a mix of imperative and functional programming.
But you can rewrite it in a more functional style.
The lines 397-400 can be rewritten as:

      cf.modules()
         .stream()
         .map(ResolvedModule::reference)
         .forEach(mref -> map.put(mref.descriptor().name(), mref));

The lines 406-415 can be rewritten as:

      otherMods
          .stream()
          .map(finder::find) // After this step you can filter out all
empty Optionals.
                                      // But I don't think it is really needed.
          .forEach(
              o -> o.ifPresent(mref -> {
                  map.putIfAbsent(mref.descriptor().name(), ref);
                  mrefs.add(mref);
              }
          );

As you see there is no need for the stupid else-clause in the lines
412-414 and there is no need to call Optional.get().

Scala's Option class has also the #get()-method. But I have never seen
that someone asked to deprecate it and to add a new one. And in my
Scala projects I have never used it.

And like others I have also some wishes:

1. I think Optional should implement Iterable interface. You can use then
    Optional everywhere where you can use Iterable today. And you will get
    the #forEach()-method which I miss sometimes after using Scala's
Option class.

2. Please add Optional#isEmpty() method. The #isEmpty()-method is useful
    when you want to filter out empty Optionals from a stream. Today I
have to write
    the lambda o -> !o.isPresen(). With the new Optional#isEmpty()
method I can use
    the method reference Optional::isEmpty.

3. Please add Option#orNull() method. It is easier to read than
Optional.orElse(null).

4. I think Optional should implement Serializable interface.
    Currently the JEE developers cannot use it as return and parameter types
    of methods of the session bean's remote interface. This is what we have
    to write today:

      public Whatever getBestMatch(String someCriteria) {
           return someOtherSrvice
             .findAll(someCriteria)
             .stream()
             .map(...)
             .filter(...)
             .sorted(MyComparator::new)
             .findFirst()
             .orElse(null);
      }

    Personally I would like to omit orElse(null) and just return the Optional
    returned by #findFirst(). But because this method can be called by
a remote client
    using RMI and RMI requires that all objects must be Serializable,
I cannot use Optional.
    We have now this new cool API in JDK and we cannot use it in JEE
applications.
    How stupid is that?

One off-topic wish:

    Please integrate Tagir's StreamEx library (or at least some parts of it)
    into JDK's Stream API. After adding his library to our product I see that
    developers move away from JDK's Stream API because his library is
    more useful than the standard Stream API.

   @Tagir: Thank you very much for StreamEx! Great job! :-)


As an average Java developer and an user of the Stream API and
the Optional class, I vote against deprecating of the Optional.get()-method.
(We have a democracy here, haven't we? :-D)

Best regards,
Andrej Golovnin



More information about the core-libs-dev mailing list