Java Optional Shortcomings
Disclaimer : The content of this blog are my views and understanding of the topic. I do not intend to demean anything or anyone. I am only trying to share my views on the topic so that you will get a different thought process and angle to look at this topic.
Java Optional looks like it solves the issue of NullPointerException but it has inbuilt design shortcomings related to restriction on method calling. When we start using it we realize that there are chances that it will throw NullPointerException or NoSuchElementException whichever suits the case at hand. Java has tried to reduce its probability by relying on meta-annotations which help IDE (Integrated Development Environment) to point out an issue to Developer but in this ever-changing Technological World, how many Developers take heed of highlighted issues which are highlighted by some color coding or some other mechanism? Let’s examine these with a simple example:
NullPointerException Still Exists
I do not deny the fact that Java Optional is beautifully designed but I believe there is always some scope of improvement when you want to achieve perfection in Design. On reading the Oracle Javadoc, one will observe the below API method:
The API method has documented that it will throw a NullPointerException if value is null. Now I was wondering, if Java Optional is here to remove NullPointerException, then it should not encourage such throws clause. It would be better to return an Empty Optional.
NoSuchElementException is the Distant Brother of NullPointerException
NullPointerException, also-known-as Billion Dollar Mistake, is a critical issue to-date. Everyone thought Java Optional will solve the issue. The truth is: It reduces the probability of occurrence of NullPointerException but is not the full-fledged solution for the same. Lets check below API Javadoc:
It’s tempting to use a get method of the Optional class, but do remember that NoSuchElementException is being thrown when the provided Optional is Optional.empty() or Optional.ofNullable(…). When a code is written in such a way that it returns an Optional of some kind, the consuming code performs some mapping using map function of optional, and eventually we perform get ( since the API method is having a catchy name) then we exhibit the exceptional case.
Note: The failure occurs at line no 12 which is bypassing map function.
There are two cases:
Either code returns an Empty Optional: It is recommended that we should return an empty optional if we want to represent no result.
Code returns an Optional.ofNullable(<Something or some method call or some expression>) : If the argument to this Nullable is null then it will fail when we call get above.
Hence, Java recommends to use Optional.orElse(…) or Optional.orElseGet(…). Now I am wondering, if orElse and orElseGet safeguards us from NoSuchElementException, then why did Java provide get method? Wouldn’t it be better if flexibility was not provided to use get method for which its Developer’s Responsibility to check Optional.ifPresent()?
We all know that it’s easy to remember our rights but we tend to ignore our responsibilities.
Brian Goetz ( Java’s language architect ) has mentioned:
Optional is intended to provide a limited mechanism for library method return types where they’re needed to be a clear way to represent “no result,” and using null for such, was overwhelmingly likely to cause errors.
Having named the class as Optional, it’s popularly marketed as a replacement to NullPointerException. It seems that the intent of creation of Optional by Language Experts was diluted by general public. We know that the creator always creates something with a different intent but the users use it as per their convenience.
I think that the way the class is named as Optional it should be used to clearly indicate the consumer that a parameter or returned value is optional. It make the code clear and readable that it will handle optional value. Java being a statically typed language has to rely on such mechanisms, but I think when writing a code it’s good to be elaborative like Java rather than creating a concise code which may lead to mis-understanding, as all of us think differently and our understanding differs when it’s fueled by our unique creativity. Moreover, if method returns an Optional of some kind, a Developer should think at least once that it may or may not return a value and handle the scenario elegantly. Do remember to use the Optional API methods diligently considering the above analysis. Similarly, you can create a wrapper class like this for any Mandatory field (Just food for thought).
A key take-away from this analysis is that your intent of Designing a class should be clear. A name of the class and its Design matters. Provide only those API methods which will be true to your intent. Ensure that you provide only the required flexibility to consumers of your code. Constraints cannot be misused, but flexibility can be.
We believe that people should adhere to law to maintain order and avoid chaos. Most of the time we provide limited flexibility and adding more constraints but we should properly choose what constraints should be applied and what flexibility can be given. A clear distinction of this would help avoid blunders which may be costly. Technology should be assistive with proper constraints since human errors are unavoidable.
I am an Agile Full Stack Developer, who is keenly interested in finding the answers to WHAT, HOW & WHY questions of Software Development. I believe in being Language Independent for writing a Software code. I contribute my knowledge to the developer society through blogs, and channel my artistic skills through every walks of life, including Software Development!