{"id":1290,"date":"2012-07-11T00:39:02","date_gmt":"2012-07-10T22:39:02","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=1290"},"modified":"2012-07-11T00:39:02","modified_gmt":"2012-07-10T22:39:02","slug":"java-8-lambda-in-details-part-i-closure-and-mutability","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=1290","title":{"rendered":"Java 8 Lambda in details part I : Closure and Mutability"},"content":{"rendered":"<p>This article is the first one of a serie dedicated to Java 8 Lambda expressions. The purpose is not to introduce the main concepts of lambda expressions, many blogs over there do it very well. The idea is to<br \/>\nshed some light on tricky details and side effects. If you&#8217;re not familiar with the new lambda-related features in Java 8, I strongly advise to look at the following article <a href=\"http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-state-4.html\" title=\"Lambda state 4\" target=\"_blank\">http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-state-4.html<\/a><\/p>\n<p>Today we&#8217;ll look at the <strong>mutability issue<\/strong> when dealing with closures.<\/p>\n<p><!--more--><\/p>\n<blockquote><p><strong>DISCLAIMER: all the details exposed in this post were observed related to the JDK 8 demo version as of <font size=\"3\" color=\"red\">July 10th 2012<\/font>. Since the JDK is still in beta, some assertions may not hold in future<\/strong>\n<\/p><\/blockquote>\n<blockquote><p> Please note that all the example code in this post can be found on my GitHub repository <a href=\"https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details\" title=\"Java8_Lambda_In_Details\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details<\/a><\/p><\/blockquote>\n<h1>I Abstract<\/h1>\n<p> When dealing with closures, we should be aware of the fact that the closure code body can have reference on objects of its enclosing class. This leads to 2 major implications:<\/p>\n<ol>\n<li>The enclosing object instance referred to by the closure code (with the <strong>this<\/strong> keyword or <strong>any implicit unqualified reference to its fields<\/strong>) cannot be garbaged by the GC even though it hasn&#8217;t any direct reference left in the heap<\/li>\n<li>If the referred object is mutable, we may encounters some side effects<\/li>\n<\/ol>\n<p>In the rest of this post, we will focus on the second point.<br \/>\n&nbsp;<\/p>\n<h1>II Capture of variable in closure<\/h1>\n<p>Let&#8217;s consider the following code<\/p>\n<pre class=\"brush: java; highlight: [23,25,50,52]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic interface VariableCaptureInClosureSAM\n{\n\tMutableObject retrieveMutable();\n}\n\npublic class MutableObject\n{\n\tprivate String content = &amp;quot;default_content&amp;quot;;\n\n\tpublic String getContent()\n\t{\n\t\treturn content;\n\t}\n\n\tpublic void setContent(String content)\n\t{\n\t\tthis.content = content;\n\t}\n}\n\npublic class VariableCaptureInClosure\n{\n\tfinal public MutableObject mutable = new MutableObject();\n\n\tpublic VariableCaptureInClosureSAM createClosure()\n\t{\n\t\tVariableCaptureInClosureSAM lambda = ()-&amp;gt;\n\t\t{\t\n\t\t\treturn this.mutable;\n\t\t};\n\n\t\treturn lambda;\n\t}\n\n\tpublic void addToMutableContent(String toAdd)\n\t{\n\t\tthis.mutable.setContent(this.mutable.getContent() + &amp;quot; &amp;quot; + toAdd);\n\t}\n\n\tpublic void printMutableContent(String stage)\n\t{\n\t\tSystem.out.println(&amp;quot;nCurrent VariableCaptureInClosure.mutable reference : &amp;quot; + this.mutable.toString());\n\t\tSystem.out.println(&amp;quot;At stage &amp;quot; + stage + &amp;quot;, current VariableCaptureInClosure.mutable content = &amp;quot; + this.mutable.getContent());\n\n\t}\n\n\tpublic static void main(String[] args)\n\t{\n\t\tVariableCaptureInClosure variableCapture = new VariableCaptureInClosure();\n\t\tVariableCaptureInClosureSAM lambda = variableCapture.createClosure();\n\n\t\tMutableObject mutableFromClosure = lambda.retrieveMutable();\n\t\tSystem.out.println(&amp;quot;nmutableFromClosureBeforeMutation reference : &amp;quot; + mutableFromClosure.toString());\n\t\tSystem.out.println(&amp;quot;mutableFromClosureBeforeMutation content = &amp;quot; + mutableFromClosure.getContent());\n\n\t\tvariableCapture.printMutableContent(&amp;quot;BEFORE MUTATION&amp;quot;);\n\t\tvariableCapture.addToMutableContent(&amp;quot;mutable&amp;quot;);\n\t\tvariableCapture.printMutableContent(&amp;quot;AFTER MUTATION&amp;quot;);\n\n\t\tSystem.out.println(&amp;quot;nmutableFromClosureAfterMutation reference : &amp;quot; + mutableFromClosure.toString());\n\t\tSystem.out.println(&amp;quot;mutableFromClosureAfterMutation content = &amp;quot; + mutableFromClosure.getContent());\n\t\tSystem.out.println(&amp;quot;&amp;quot;);\n\t}\n}\n<\/pre>\n<p> First we declare a SAM (<strong>S<\/strong>ingle <strong>M<\/strong>ethod <strong>I<\/strong>nterface) with the abstract <em><strong>MutableObject<\/strong> retrieveMutable()<\/em> method.<\/p>\n<p> The <strong>MutableObject<\/strong> is a plain POJO with a String field and a setter to change its value and hence make it mutable. Please note that this <strong>MutableObject<\/strong> is initialized with &#8220;<strong>default_content<\/strong>&#8221; as content.<\/p>\n<p> In the <strong>VariableCaptureInClosure<\/strong> class, we define the method <em>createClosure()<\/em> whose purpose is to return a lambda expression that captures the <strong>final<\/strong> <em>mutable<\/em> field (<strong>line 25<\/strong>)<\/p>\n<p> In the <em>main()<\/em> method, we start by retrieving the lambda expression (<strong>line 50<\/strong>) then we get a reference to the mutable object (<strong>line 52<\/strong>)<\/p>\n<p> We then display the reference on this mutable object and its content:<\/p>\n<blockquote><p>\nmutableFromClosureBeforeMutation reference : fr.doan.lambda.mutability.MutableObject@<strong>8c5a4f<\/strong><br \/>\nmutableFromClosureBeforeMutation content = default_content\n<\/p><\/blockquote>\n<p> Next, we get the reference of the <em>mutable<\/em> object from the <strong>VariableCaptureInClosure<\/strong> instance and display its content (<strong>lines 53-54<\/strong>):<\/p>\n<blockquote><p>Current VariableCaptureInClosure.mutable reference : fr.doan.lambda.mutability.MutableObject@<strong>8c5a4f<\/strong><br \/>\nAt stage BEFORE MUTATION, current VariableCaptureInClosure.mutable content = default_content\n<\/p><\/blockquote>\n<p> At this stage, we can clearly see that both instances of <strong>MutableObject<\/strong> class, the one returned by the lambda expression and the one of the <strong>VariableCaptureInClosure<\/strong> instance, are identical, not surprising.<\/p>\n<p> Now the idea is to change the content of this mutable object by calling the method <em>addToMutableContent(String toAdd)<\/em> and print out the result.<\/p>\n<blockquote><p>Current VariableCaptureInClosure.mutable reference : fr.doan.lambda.mutability.MutableObject@<strong>8c5a4f<\/strong><br \/>\nAt stage AFTER MUTATION, current VariableCaptureInClosure.mutable content = default_content <strong>mutable<\/strong><\/p><\/blockquote>\n<p>The content has been actually changed. Now if we check again the <strong>MutableObject<\/strong> instance from the closure, its content has been also changed and it&#8217;s expected.<\/p>\n<blockquote><p>mutableFromClosureAfterMutation reference : fr.doan.lambda.mutability.MutableObject@<strong>8c5a4f<\/strong><br \/>\nmutableFromClosureAfterMutation content = default_content <strong>mutable<\/strong><\/p><\/blockquote>\n<p>This small example shows us that a lambda expression can keep a reference on a object from its enclosing class (but it&#8217;s not <strong>exactly<\/strong> that, we&#8217;ll see later in the next chapter). If the object is mutable, changes can come both from the owning class and the lambda expression.<\/p>\n<p> The new collection API enhancement in Java 8 provides some usefull method to work in parallel on collection. You should take care about your object mutability if you are working on an multi-threaded environment since it may lead to serious side effects. <\/p>\n<p> Please notice that the mutable field being declared as final (<strong>line 23<\/strong>) does not help it being less mutable since <strong>mutability<\/strong> and <strong>final variable<\/strong> are two distinct concepts (most people are still confused about it)<\/p>\n<blockquote><p> The above code example can be found on GitHub at <a href=\"https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details\" title=\"https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details<\/a>. Just execute the <strong>VariableCaptureInClosure.bat<\/strong>(<strong>VariableCaptureInClosure.sh<\/strong>) script<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h1>III Non final variable<\/h1>\n<p>In the following example, we make the previous <em>mutable<\/em> field non final.<\/p>\n<pre class=\"brush: java; highlight: [3,9,35,36,37,39]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic class NonFinalVariableCaptureInClosure\n{\n\tpublic MutableObject mutable = new MutableObject();\n\n\tpublic VariableCaptureInClosureSAM createClosure()\n\t{\n\t\tVariableCaptureInClosureSAM lambda = ()-&amp;gt;\n\t\t{\n\t\t\treturn this.mutable;\n\t\t};\n\t\treturn lambda;\n\t}\n\n\tpublic void addToMutableContent(String toAdd)\n\t{\n\t\tthis.mutable.setContent(this.mutable.getContent() + &amp;quot; &amp;quot; + toAdd);\n\t}\n\n\tpublic void printMutableContent(String stage)\n\t{\n\t\tSystem.out.println(&amp;quot;nCurrent VariableCaptureInClosure.mutable reference : &amp;quot; + this.mutable.toString());\n\t\tSystem.out.println(&amp;quot;At stage &amp;quot; + stage + &amp;quot;, current VariableCaptureInClosure.mutable content = &amp;quot; + this.mutable.getContent());\n\n\t}\n\n\tpublic static void main(String[] args)\n\t{\n\t\tNonFinalVariableCaptureInClosure variableCapture = new NonFinalVariableCaptureInClosure();\n\t\tVariableCaptureInClosureSAM lambda = variableCapture.createClosure();\n\n\t\tMutableObject mutableFromClosureBeforeRefChange = lambda.retrieveMutable();\n\t\tSystem.out.println(&amp;quot;nmutableFromClosureBeforeRefChange reference : &amp;quot; + mutableFromClosureBeforeRefChange.toString());\n\t\tSystem.out.println(&amp;quot;mutableFromClosureBeforeRefChange content = &amp;quot; + mutableFromClosureBeforeRefChange.getContent());\n\n\t\tMutableObject newMutable = new MutableObject();\n\t\tnewMutable.setContent(&amp;quot;new_content&amp;quot;);\n\t\tvariableCapture.mutable = newMutable;\n\n\t\tMutableObject mutableFromClosureAfterRefChange = lambda.retrieveMutable();\n\n\t\tSystem.out.println(&amp;quot;nmutableFromClosureAfterRefChange reference : &amp;quot; + mutableFromClosureAfterRefChange.toString());\n\t\tSystem.out.println(&amp;quot;mutableFromClosureAfterRefChange content = &amp;quot; + mutableFromClosureAfterRefChange.getContent());\n\t\tSystem.out.println(&amp;quot;&amp;quot;);\n\t}\n}\n<\/pre>\n<p> The code is quite straightforward. We create a new <strong>MutableObject<\/strong> and assign it to the <em>mutable<\/em> field of the <strong>NonFinalVariableCaptureInClosure<\/strong> instance (<strong>lines 35-37<\/strong>). The output shows:<\/p>\n<blockquote><p>\nmutableFromClosureBeforeRefChange reference : fr.doan.lambda.mutability.MutableObject@<strong>14f7121<\/strong><br \/>\nmutableFromClosureBeforeRefChange content = <strong>default_content<\/strong><\/p>\n<p>mutableFromClosureAfterRefChange reference : fr.doan.lambda.mutability.MutableObject@<strong>8c5a4f<\/strong><br \/>\nmutableFromClosureAfterRefChange content = <strong>new_content<\/strong><\/p><\/blockquote>\n<p> This result is more surprising. We expect that the second call to <em>lambda.retrieveMutable()<\/em> (<strong>line 39<\/strong>) will return us the old <strong>MutableObject<\/strong> instance (<strong>14f7121<\/strong>) but it&#8217;s not the case.<\/p>\n<p> <font color=\"red\">What happends under the hood is that the lambda expression captures its enclosing context by keeping a reference on the <strong>NonFinalVariableCaptureInClosure<\/strong> instance via the <strong>this<\/strong> keyword in <em>return <strong>this<\/strong>.mutable;<\/em> (<strong>line 9<\/strong>) and not a reference to the <strong>MutableObject<\/strong> itself&#8230;<\/font><\/p>\n<p>So the second call to <em>lambda.retrieveMutable()<\/em> returns the new instance of <strong>MutableObject<\/strong> we just create and assign to the <strong>NonFinalVariableCaptureInClosure<\/strong> object.<\/p>\n<blockquote><p> The above code example can be found on GitHub at <a href=\"https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details\" title=\"https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/Java8_Lambda_In_Details<\/a>. Just execute the <strong>NonFinalVariableCaptureInClosure.bat<\/strong>(<strong>NonFinalVariableCaptureInClosure.sh<\/strong>) script<\/p><\/blockquote>\n<p> To be continued &#8230;<\/p>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article is the first one of a serie dedicated to Java 8 Lambda expressions. The purpose is not to introduce the main concepts of lambda expressions, many blogs over there do it very well. The idea is to shed&#8230;<br \/><a class=\"read-more-button\" href=\"https:\/\/www.doanduyhai.com\/blog\/?p=1290\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,8],"tags":[],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1290"}],"collection":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1290"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1290\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}