After the article of last week “Optional in collections” today I can’t help but talking a bit more about the same beast. A bit more detail.
The class originally introduced by Google Guava and later included in the Java 8 package is simply a wrapper that wraps an optional object. The wrapped object is optional in the sense that it is either there or there is no object in the wrapping, in which case it is empty. There is not too much magic there. The wrapping code, the class insist that the object wrapped is not . After all is and not an object. An object is never . Only a reference to an object can be .
These are nuances, fine details; but important fine details. After all, these fine details are those that required the introduction of . Average java coder does not see the importance of such tiny details. They think that is just as good as a variable to the wrapped object itself assuming that the variable can also be . At some level they are right. At their own level.
That level says that the good code works, can be understood and that is it. Most of enterprise legacy code that run banks, insurance companies, pace makers and weapons were made on this level. You can not do about it, just hope that you have the luck and a software bug will not select your house, bank account or body (in case of medical device) in a “bomb” explode there. What you can do is to understand the issue and do your part to slowly improve the situation. It will take a few generations unless we all are wiped out before that.
“Code working” and “possible to understand” are the very basic requirement for software. Some old times we said that if the software runs then it was ok and for the maintenance it was enough if there were two “person” who could understand the code: the coder who created it and God, who created the coder. Fortunately there are also levels higher. (I mean above the coder. Not above God.)
“Code working” and “easy (not so hard) to understand” are the next level. This is important in case you have to debug the code and need to identify the root cause of some malfunction. “Code working” and “easy to modify” are again new steps up the ladder. I had seen code that I could easily understand. The code was running. But the dependencies between the different modules were so complex like a macrame or a traditional Italian spagetti. Wherever I wanted to change something to fix a bug here, there were a few other places where the program started to fail. Easy to modify: that code was not.
The next level is “code working”, “easy to modify” and “hard to create bad modifications”. This means that the code provides style and internal data structures and APIs that the maintaining person will follow to some level and will create a working modified code that still works, easy to understand and to modify. This is the point where we get to the point of .
When a method returns is says that it may return something or just nothing. may return an but it may just return an empty , which means: there was no that I could return. Why is it any better than returning an that may optionally be ?
Optional method return value
The answer is that in case of returned you can not:
integer = methodReturningIntegerOrNull(); otherInteger = integer +1;
that causes NPE. Why you do that? Because you forget to check, and the JavaDoc mentions the possibility somewhere at the end of the description that is not visible in the mouse over window when you code. In case of you are forced to:
optionalInteger = methodReturningOptionalInteger();
if( optionalInteger.isPresent() ){
otherInteger = optionalInteger.get() +1;
}Still there is a small chance that you will write:
optionalInteger = methodReturningOptionalInteger(); otherInteger = optionalInteger.get() +1;
but in that case you deserve what you get.
helps you to create more code and less documentation. It gives a semantic to pass on some optional value in a way that is harder to neglect than a nullable value. It says: I do not trust you handling properly, therefore I give you a wrapped object so you have to handle optionality explicitly.
If you consider that you can easily answer the questions
- requiring as a method argument
- having a field optional.
are good ideas.
Optional method argument
There are pros and cons. When the argument says:
countFrom(Optional<Date> from, Date to);
it is clear that the value may be missing and there should be some special default semantics when an absent value is passed. On the other hand the caller may pass to get the special behavior. It is less likely that the caller will pass just by mistake neglecting the optionality. Even if the argument is the argument actually passed can still be and I expect that the method throws NPE in this case. Last, but not least there is another danger introducing : the caller may pass an embracing an object that is not a . Generics can be circumvented in Java easy and a sloppy coder may pass a wrong . It means that you have to implement assertions in your method:
- argument is not null,
- argument is of the proper type.
Also recall that , in case of a method return value says: I do not trust you handling properly, therefore I give you a wrapped object so you have to handle optionality explicitly. What would this message be when you create the API requiring as an argument? Please do not trust me! Give me only because even I do not trust myself to handle a value properly. Weird… On the other hand I trust that you will not pass or wrong type.
In my opinion: in this case using does not deliver more value than having proper documentation for the API and does not force the caller to behave better than it would anyway. On the other side you put extra code on your own shoulder.
Give to code you trust, accept it from code that does not trust your code but do not request it! Trust yourself!
Private Optional Fields
When you declare a local, private field to be you will force the developer of the class itself to pay more attention to the optional feature of the field. The cost of this is the extra wrapper, the extra clutter in the code handling optional. On the other side there is no much gain, because you can get the same level of quality extending your unit tests checking all cases where value of the field is to be considered. Since all the code is in the hand of the current developer being responsible for the whole code there is no benefit of . It is again, like you not trusting yourself. That is a serious issue needing more and different treatment than what Java class can provide.
Optional in functional programming
You can use to program Java in functional programming style if you want, but Java is not a functional language and optional and lambda and the functional style methods alone will not make it to be. But that is a different topic for later.
| Reference: | Use of optional is optional from our JCG partner Peter Verhas at the Java Deep blog. |
Thank you!
We will contact you soon.
Peter VerhasSeptember 3rd, 2015Last Updated: September 3rd, 2015

This site uses Akismet to reduce spam. Learn how your comment data is processed.
I use it in cached methods return values, if optional is null, it implies there is no entry in cache, if optional is not null but value is absent then the value is null in the cache for the key, otherwise, the caller has no clue whether what the null means.
The idea is to force the developer (it is the intention at least) to verify that a value or object reference is not null and thus ensure that operations he/she is performing are null safe operations, as Peter has mentioned in this article: “integer = methodReturningIntegerOrNull(); otherInteger = integer +1;” //Good way if (Optional.isPresent()){} //No so good if (object_optiona == null) Even with the advantages offered by the use of Optional, if there is not an object within the Optional and the developer does not prove it, but he / she uses the Optional.get () method immediately, it is likely… Read more »
Completely agreed that while NPEs can still happen unless developer correctly uses optional, my use case was about returning an object from a cached method that differentiates whether the element not exists in cache vs element exists and it’s value is null.
May be I should also change this to always return optional with a wrapped object that holds null. Or an optional containing optional?
In that situation you have three different cases: – value is not cached – value is cached and it is null – value is cached and it is not null In your data model you separate these three cases into two branches, something like – value is not cached (return value is null) or else – return the cached value wrapped in an optional that may be ‘absent’ Seems to be logical after I analyzed it. The problem is that this is logical only after you understood the intent of the developer. Java coding has to be simple and clear.… Read more »