Java 8 SE Optional, a strict approach

About two weeks ago Stephen Colebourne presented his pragmatic approach to using Optional. If you read it, you might have guessed from my previous recommendations that I don’t agree.


I have to start with a disclaimer but then I’ll jump right in and explain why I think his approach is less then ideal.

All quotes that are not attributed to somebody else are taken from Stephen’s post. While not strictly necessary I recommend to read it first. But don’t forget to come back!

I created three gists, which I present throughout the post: the same example in Stephen’s version, my basic version, and my extended version.


Stephen Colebourne is a Java legend. Quoting Markus Eisele’s Heroes of Java post about him:

Stephen Colebourne is a Member of Technical Staff at OpenGamma. He is widely known for his work in open source and his blog. He created Joda-Time which is now being further developed as JSR-310/ThreeTen. He contributes to debates on the future of Java, including proposals for the diamond operator for generics and FCM closures, both of which are close to the adopted changes in Java 7 and 8. Stephen is a frequent conference speaker, JavaOne Rock Star and Java Champion.

I had the pleasure to contribute to Stephen’s Property Alliance and this reinforced my opinion of him as an extremely competent developer and a very deliberate person.

All of which goes to say that if in doubt, trust him over me.

Then there is the fact, that his approach is rooted in the axiom that Optional should solely be used as a return type. This is absolutely in line with the recommendations of those who introduced the class in the first place. Quoting Brian Goetz:

Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe or Some type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent “no result”, and using null for such was overwhelmingly likely to cause errors.

[…] You should almost never use it as a field of something or a method parameter.

So if in doubt, trust his opinion over mine.


Of course, even better than to just trust anyone is to make up your own mind. So here are my arguments in contrast to Stephen’s.

Basic Points

These are Stephen’s five basic points:

  1. Do not declare any instance variable of type Optional.
  2. Use null to indicate optional data within the private scope of a class.
  3. Use Optional for getters that access the optional field.
  4. Do not use Optional in setters or constructors.
  5. Use Optional as a return type for any other business logic methods that have an optional result.

Here are mine:

  1. Design your code to avoid optionality wherever feasibly possible.
  2. In all remaining cases, prefer Optional over null.


Let’s compare examples. His is:

I like that no consumer of this class can receive null. I dislike how you still have to deal with it – within the class but also without.

This would be my (basic) version:

There are simply no nulls, here.


A Constrained Problem

Within the object, the developer is still forced to think about null and manage it using != null checks. This is reasonable, as the problem of null is constrained. The code will all be written and tested as a unit (you do write tests don’t you?), so nulls will not cause many issues.

Do you see how his constructor allows one of the arguments to be null? And the only way to find out which one requires you to leave what you are doing and look at some other class’ code. This is no big thing but unnecessary nonetheless.

Even leaving this aside, the problem is not as constrained as it should be. Assuming that everybody hates comments, we have to assume they are not there, which leaves the constructor internals and the getter’s return type to tell you that the field is nullable. Not the best places for this information to jump out at you.

His argument for tests might get crushed by numbers. If all tests include all fields, each optional field would double the number of tests as each should be run for the null and the non-null case. I’d prefer having the type system as a first line of defense here.

On the other hand, this pain might convince the developer to maybe find a solution with less optionality within a single class.


Stephen correctly points out that an instance created for a method return value that is then quickly discarded (which is typical for uses of Optional) has little to no costs. Unlike an Optional field, which exists for the entire life time of the containing object and adds an additional layer of indirection from that object to the Optional’s payload.

For him this is a reason to prefer null.

While it is easy to claim this is “premature optimization”, as engineers it is our responsibility to know the limits and capabilities of the system we work with and to choose carefully the point where it should be stressed.

I agree. But to me part of choosing carefully means to profile first. And if someone shows me convincing arguments that in his concrete case replacing some Optional fields with nullable fields causes a noticeable performance gain, I’d rip them stupid boxes right out. But in all other cases I stick with the code I consider more maintainable.

By the way, the same argument could be made for using arrays instead of ArrayLists or char-arrays instead of strings. I’m sure nobody would follow that advice without considerable performance gains.

This recurring topic in the discussion deserves some attention, though. I will try to find some time to profile some use cases that I think would be interesting.


While it is a minor point, it should be noted that the class could be Serializable, something that is not possible if any field is Optional (as Optional does not implement Serializable).

I consider this to be solved. Causes a little extra work, though.


[I]t is my experience that having Optional on a setter or constructor is annoying for the caller, as they typically have the actual object. Forcing the caller to wrap the parameter in Optional is an annoyance I’d prefer not to inflict on users. (ie. convenience trumps strictness on input)

While writing annoying code can be fun I see his point. So don’t force users, overload your methods:

Of course this doesn’t scale well with many optional fields. In that case, the builder pattern will help.

Then there is the fact that if our nullable postcode has a setter, the developer working on some other code must again stop and come looking at this class to determine whether she can pass null. And since she can never be sure, she has to check for other getters, too. Talking about annoying code…

With a field of type Optional the setter could look like this:

Again, all null values are immediately answered with an exception.


On the downside, this approach results in objects that are not beans.

Yep. Having a field of type Optional doesn’t suffer from that.


It should not be overlooked that we’re discussing details here. Our goal is the same and we’re proposing similar ways of getting there.

If adopted widely in an application, the problem of null tends to disappear without a big fight. Since each domain object refuses to return null, the application tends to never have null passed about. In my experience, adopting this approach tends to result in code where null is never used outside the private scope of a class. And importantly, this happens naturally, without it being a painful transition. Over time, you start to write less defensive code, because you are more confident that no variable will actually contain null.

This is a great goal to achieve! And following Stephen’s advice will get you most of the way there. So don’t take my disagreement as a reason to not use Optional at least that much.

All I’m saying is that I see little reason to stop short of banning null even more!


I addressed and hopefully refuted a number of arguments against using Optional whenever something is nullable. I hope to have shown that my stricter approach goes further in exorcising null. This should free up your mind to think about more relevant problems.

The price to pay might be a shred of performance. If someone proves that it is more, we can still return to null for those specific cases. Or throw hardware at the problem. Or wait for value types.

What do you think?

Share & Follow

You liked this post? Then share it with your friends and followers!
And if you like what I'm writing about, why don't you follow me?

Other Posts