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:
Like this:
Like Loading...
Published by lukaseder
I made jOOQ
View all posts by lukaseder
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.
You can already use one of these @Nonnull or @NotNull annotations:
https://stackoverflow.com/q/4963300/521799
Well, I’d like it to be part of the language. The JSR for this seems to have been stalled since 2006. (http://jcp.org/en/jsr/detail?id=305)
I guess, JSR 305 was stalled in favour of JSR 303 (http://jcp.org/en/jsr/detail?id=303, which won’t be part of the language, of course)
JSR 303 seems to be specifically about JavaBeans(TM).
Yes, more inconsistency and redundancy between the various approaches of doing things. Yay ;-)
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.
Thus, “paranoid” :-) I don’t intuitively trust this type (yet).
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.
Yes, yes, I agree with the general idea of having an
Optional
. My fluent APIs (specifically: jOOX) tend to rarely returnnull
either. It’s just that thisOptional
, 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.What do you mean by that?
Optional<T>
provides more type information than plainT
? Could you give me an example? After all, with type erasure, theOptional
type doesn’t contain any reference toT
orClass<T>
at runtime, so it feels the same to me as having(T) null
.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?
Don’t get me started on getters and setters ;-)
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.
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…