On Java 8’s introduction of Optional

I had recently discovered the JDK 8’s addition of the Optional type. The Optional type is a way to avoid NullPointerException, as API consumers that get Optional return values from methods are “forced” to perform “presence” checks in order to consume their actual return value. More details can be seen in the Javadoc. A very interesting further read can be seen here in this blog post, which compares the general notion of null and how null is handled in Java, SML, and Ceylon: http://blog.informatech.cr/2013/04/10/java-optional-objects “blank” and “initial” states were already known to Turing . One could also argue that the “neutral” or “zero” state was required in the Babbage Engine, which dates back to Ada of Lovelace in the 1800′s. On the other hand, mathematicians also prefer to distinguish “nothing” from “the empty set”, which is “a set with nothing inside”. This compares well with “NONE” and “SOME”, as illustrated by the aforementioned Informatech blog post, and as implemented by Scala, for instance. Anyway, I’ve given Java’s Optional some thought. I’m really not sure if I’m going to like it, even if Java 9 would eventually add some syntactic sugar to the JLS, which would resemble that of Ceylon to leverage Optional on a language level. Since Java is so incredibly backwards-compatible, none of the existing APIs will be retrofitted to return Optional, e.g, the following isn’t going to surface the JDK 8:

public interface List<E> {
    Optional<E> get(int index);
    [...]
}

Not only can we assign null to an Optional variable, but the absence of “Optional” doesn’t guarantee the semantics of “SOME”, as lists will still return “naked” null values. When we mix the two ways of thinking, we will wind up with two checks, instead of one

Optional<T> optional = // [...]
T nonOptional = list.get(index);

// If we're paranoid, we'll double-check!
if (optional != null && optional.isPresent()) {
    // do stuff
}

// Here we probably can't trust the value
if (nonOptional != null) {
    // do stuff
}

Hence… -1 from me to Java’s solution

Further reading

Of course, this has been discussed millions of times before. So here are a couple of links:

23 thoughts on “On Java 8’s introduction of Optional

  1. More boilerplate, oh joy. And if someone is lazy and just does a get() without checking isPresent() they just get a different RuntimeException than they would trying to dereference null. I’d much rather have a way of declaring that a function can’t return null.

  2. I would argue that if a method returns an optional reference you should not need to null-check that reference, pretty much for the same reason that we don’t null-check all references in our code. We should assume that methods returning an optional guarantee the invariant that they will always return a non-null value. This would be like the convention of not returning null for methods whose signature has a collection or an array as their return type. In those case, the convention is to return an empty collection or array. So, most of us, rarely null-check this type of return values and assume they reference something.

    Regarding the need to check for isPresent, well, that would be pretty much the same check would need to do for a null reference, so I would say it is the same boilerplate. I do see value in the use of the Optional type in the fact that the API can explicitly state that it may or may no return a value through the use of an explicit type.

  3. The reason that Optional is better than `null` is that type information is preserved. `null` could be any type but an absent Optional clearly was expecting type T. I don’t want to get on a rant and don’t expect anyone that has not used an FP extensively or loves OOP to understand the benefit of Optional. With Java 7 and above the type information is becoming increasingly reified.
    Also clearly Java has and is continuously moving towards FP and thats because Java is mainly service oriented which is a natural fit for FP (separation of behavior and state).

    I understand the practicality of returning null as its generally KISS but I also understand API’s like Guava that aim to be consistent and never return null and thus Optional is the better answer.

    In my own library JIRM is use Optional extensively. I find it makes me think about types and whether something is truly optional or not. So I never return null and if something can I return Optional. At the end of the day that’s what its really about: Communication and consistency.

    1. Yes, yes, I agree with the general idea of having an Optional. My fluent APIs (specifically: jOOX) tend to rarely return null either. It’s just that this Optional, as it is in the JDK 8 right now makes all the pre-existing APIs ambiguous, as non-optionals aren’t guaranteed to be non-null. I just feel that this solution is not very thorough. Anyway, maybe, I’m not seeing the big picture yet.

      With Java 7 and above the type information is becoming increasingly reified.

      What do you mean by that?

      but an absent Optional clearly was expecting type T

      Optional<T> provides more type information than plain T? Could you give me an example? After all, with type erasure, the Optional type doesn’t contain any reference to T or Class<T> at runtime, so it feels the same to me as having (T) null.

  4. I find this Optional quite interesting, the biggest problem is that unlike in ceylon or kotlin, it wasn’t part of the language from the start and thus, as Lukas wrote, most of the java ecosystem won’t be consistent with it.
    Other than that, I usually consider anything that allows better compile time checking as a benefit.

    PS: still no property support in java8, do people love generating crappy getter/setters that much?

  5. Haven’t looked into Java’s Optional yet, but in Scala et al the purpose of Option is to NOT surround it with a if( somecheck ) code, but to provide a continuation that is or is not called. So an operation applied to an E in Some results in the operations value (wrapped into an Option again), while applying it to None results in None again. Thus one can chain operations without any if-isPresent checks.
    This way the chaining of operations flows naturally.

    1. You’re right, and I really value elegant implementations such as Scala’s or Ceylon’s. That’s how things should be. In Java, unfortunately, merely adding an Optional type just isn’t as powerful…

Leave a Reply to lukasederCancel reply