{"id":2327,"date":"2019-08-06T22:10:29","date_gmt":"2019-08-06T21:10:29","guid":{"rendered":"http:\/\/www.andygibson.net\/blog\/?p=2327"},"modified":"2019-08-28T22:20:18","modified_gmt":"2019-08-28T21:20:18","slug":"optionals","status":"publish","type":"post","link":"http:\/\/www.andygibson.net\/blog\/programming\/optionals\/","title":{"rendered":"Optionals"},"content":{"rendered":"\n<p>I have to confess, I was sceptical when I first read about the new <code>Optional<\/code> class that was being introduced in Java 8 way back when. Its only over the last few years I have come to really appreciate how it can shape the way we define method signatures and invoke them. This post covers the various ways this simple class can help you write clearer and more robust code.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>When returning a value from a method, you want to return one of three things, either return the actual result, return an unknown (<code>null<\/code>) value, or throw an exception.<br> The first case is the happy path which most developers code for as it hopefully meets most cases. Returning a null can often be overlooked unless the developer is very conscientious or there is already an expectation that the result is likely to be null. The third option is that an exception can be thrown from the method if it is unable to complete the operation. The problem here is that we have a fairly loose contract with the client and leave it up to the caller to be aware of the different outcomes.<\/p>\n\n\n\n<p>Once we have a value from a method, you typically want to do one of three things when it is null. Use a default value, throw an exception or change program flow to not use it. The following 3 examples show how this is done in a pre-Optional world: <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/\/Throw Exception\nInteger size = calculateSize();\nif (size == null) {\n  throw new NullPointerException(&quot;Couldn&#039;t calculate size&quot;);\n}\n\/\/do something with size.\n\n\n \n\/\/Default Value\nInteger size = calculateSize();\nif (size == null) {\n  size = DEFAULT_SIZE;\n}\nallocateSpace(size);\n\n\n\/\/Different code path:\nInteger size = calculateSize();\nif (size != null) {\n  allocateSpace(size);\n}\n\n\/\/carry on\n\n<\/pre><\/div>\n\n\n<p>Because we have always been able to deal with null values like this, I wasn&#8217;t blown away by the prospect of the <code>Optional<\/code> class. However, the problem with the above is that we must always remember to handle a null result and inevitably at some point, someone will end up writing :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nInteger size = calculateSize();\nallocateSpace(size);\n<\/pre><\/div>\n\n\n<p>This will create code that is prone to sporadic unhandled failures. In general we want our code to be robust, easy to use and offer the least surprises. <\/p>\n\n\n\n<p>To avoid repeating this in every invocation, we could roll the logic into our function so <code>calculateSize()<\/code> will throw an exception or return a default value. However, we might not always know which we want to do since it would depend on the context it was called in. <\/p>\n\n\n\n<h2>Optionals To The Rescue<\/h2>\n\n\n\n<p><code>Optional<\/code> values allow us to always return an object that acts as a container for the actual value that may or may not be null. We typically create a new <code>Optional<\/code> using either :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nreturn Optional.of(result);\n\nor\n\nreturn Optional.ofNullable(possibleNullValue);\n<\/pre><\/div>\n\n\n<p>If the value you return may be <code>null<\/code>, you should use the latter version otherwise an exception will be thrown if you invoke the first syntax with a <code>null<\/code> value.<\/p>\n\n\n\n<p><code>Optional<\/code> values enable us to define the signature of the method to say the outcome could well be null and force the client to deal with it.<\/p>\n\n\n\n<p>We can query the returned <code>Optional<\/code> value and handle it differently depending on whether there is a value or not. Here are the same above 3 cases implemented as an <code>Optional<\/code> value returned from <code>calculateSize()<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/\/Default Value\nInteger size = calculateSize().orElse(DEFAULT_SIZE);\nallocateSpace(size);\n\n\/\/Throw Exception\nInteger size = calculateSize().orElseThrow(()-&gt;new RuntimeException(&quot;Couldn&#039;t calculate size&quot;));\nallocateSpace(size);\n\n\/\/Different code path\ncalculateSize().ifPresent(s-&gt; allocateSpace(s));\n\n<\/pre><\/div>\n\n\n<p>The real value of the <code>Optional<\/code> class is the semantics to say that this value could be <code>null<\/code>, forcing the developer to deal with it and providing convenience for handling <code>null<\/code> values in a different way.  Granted, just as before, someone could just incorrectly write :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nInteger size = calculateSize().get();\nallocateSpace(size);\n\n<\/pre><\/div>\n\n\n<p>But there are static analysis tools that can detect such code smells where you access an optional without checking it, and if you have proper unit test coverage (such that <code>calculateSize<\/code> returns an empty <code>Optional<\/code>) this code should be invoked with an empty optional and an error thrown.<\/p>\n\n\n\n<h3>Improving clarity. <\/h3>\n\n\n\n<p>When we return the actual object, callers of the method don&#8217;t know whether <code>null<\/code> could be returned or if the method will throw an exception without looking at either the method signature or java doc. When returning an <code>Optional<\/code>, you can safely assume that the value can be <code>null<\/code> and code defensively for it either by using one of the above solutions.<\/p>\n\n\n\n<h3>Rules to code by:<\/h3>\n\n\n\n<ul><li>If a value will always be returned then return the actual type.<\/li><li>If the method could return <code>null<\/code>, then return an <code>Optional<\/code> to let the caller know this is the case and force the client to deal with the result.<\/li><li>Throw an exception, select  default or change the program flow based on the result for the appropriate context of the caller.<\/li><\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Article about the semantic benefits of using java Optional values for returning results.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[80],"tags":[6],"_links":{"self":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/2327"}],"collection":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/comments?post=2327"}],"version-history":[{"count":9,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/2327\/revisions"}],"predecessor-version":[{"id":2350,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/2327\/revisions\/2350"}],"wp:attachment":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/media?parent=2327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/categories?post=2327"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/tags?post=2327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}