java.util.Optional fields

Brian Goetz brian.goetz at oracle.com
Fri Sep 21 07:51:18 PDT 2012


>> An alternative of throwing NoSuchElementException was replaced by
>> returning an Optional.
>
> Having Optional enables me to do fluent API thingies like:
>    stream.getFirst().orElseThrow(() -> new MyFancyException())
>
> I would speculate *this* was the intended goal for Optional.

Absolutely.

Take the example from SotL/L from the reflection library.

Old way:

for (Method m : enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
      if (m.getName().equals(enclosingInfo.getName()) ) {
          Class<?>[] candidateParamClasses = m.getParameterTypes();
          if (candidateParamClasses.length == parameterClasses.length) {
              boolean matches = true;
              for(int i = 0; i < candidateParamClasses.length; i++) {
                  if 
(!candidateParamClasses[i].equals(parameterClasses[i])) {
                      matches = false;
                      break;
                  }
              }

              if (matches) { // finally, check return type
                  if (m.getReturnType().equals(returnType) )
                      return m;
              }
          }
      }
  }

  throw new InternalError("Enclosing method not found");

Without Optional:

Method matching =
      Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
         .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
         .filter(m ->  Arrays.equals(m.getParameterTypes(), 
parameterClasses))
         .filter(m -> Objects.equals(m.getReturnType(), returnType))
         .getFirst();
if (matching == null)
     throw new InternalError("Enclosing method not found");
return matching;

This is much better, but we still have a "garbage varaiable", matching, 
which we have to test and throw before returning.

With Optional:

return
   Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
         .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
         .filter(m ->  Arrays.equals(m.getParameterTypes(), 
parameterClasses))
         .filter(m -> Objects.equals(m.getReturnType(), returnType))
         .findFirst()
         .getOrThrow(() -> new InternalError(...));




More information about the lambda-dev mailing list