{"id":1347,"date":"2012-07-12T22:43:54","date_gmt":"2012-07-12T20:43:54","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=1347"},"modified":"2012-07-12T22:43:54","modified_gmt":"2012-07-12T20:43:54","slug":"java-8-lambda-in-details-part-ii-scoping-of-this-and-effectively-final-variable-semantic","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=1347","title":{"rendered":"Java 8 Lambda in details part II : Scoping of &#8220;this&#8221; and &#8220;effectively final&#8221; variable semantic"},"content":{"rendered":"<p>In this second post, we&#8217;ll look at the scoping of the <strong>this<\/strong> keyword inside a lambda expression and the semantic of the so called &#8220;<em>effectively final<\/em>&#8221; local variables.<br \/>\n<!--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<p>&nbsp;<\/p>\n<h1>I Scoping of &#8220;this&#8221;<\/h1>\n<p> First, as a reminder, below are the principal variable scopes in Java<\/p>\n<ol>\n<li><strong>class level scope<\/strong>: the variable is accessible anywhere in the class, either statically or dynamically at class instance creation<\/li>\n<li><strong>Method scope<\/strong>: the variable is accessible only in the declaring method<\/li>\n<li><strong>Code block scope<\/strong>: the variable is accessible only in the declaring code block. <strong>A code block is a portion of code enclosed in braces {&#8230;}<\/strong>. Loops like <strong>for<\/strong>, <strong>do<\/strong>, <strong>while<\/strong> as well as <strong>static<\/strong> and <strong>synchronized<\/strong> blocks  are considered code block <\/li>\n<\/ol>\n<p> Unlike anonymous functions, a lambda expression can be considered as a simple code block with regarde to variable scoping. Consequently all scoping rules for code blocks also apply to lambda expression.<\/p>\n<p>Let&#8217;s look at the below code:<\/p>\n<pre class=\"brush: java; highlight: [3,17,27,33]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic class MutableObject\n{\n\tprivate String content = &amp;quot;default_content&amp;quot;;\n\t...\n}\npublic class ScopingOfThis\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\t\n\t\t\tMutableObject mutable = new MutableObject();\n\t\t\tmutable.setContent(&amp;quot;from_closure&amp;quot;);\n\t\n\t\t\treturn this.mutable;\n\t\t};\n\n\t\treturn lambda;\n\t}\n\n\tpublic VariableCaptureInClosureSAM createAnonymous()\n\t{\n\t\tVariableCaptureInClosureSAM anonymousClass = new VariableCaptureInClosureSAM()\n\t\t{\n\t\t\tMutableObject mutable = new MutableObject();\n\n\t\t\t@Override\n\t\t\tpublic MutableObject retrieveMutable()\n\t\t\t{\n\t\t\t\tthis.mutable.setContent(&amp;quot;from_anonymous&amp;quot;);\n\t\t\t\treturn this.mutable;\n\t\t\t}\n\n\t\t};\n\n\t\treturn anonymousClass;\n\n\t}\n\n\tpublic static void main(String[] args)\n\t{\n\t\tScopingOfThis scopingOfThis = new ScopingOfThis();\n\t\tVariableCaptureInClosureSAM sam = scopingOfThis.createClosure();\n\n\t\tMutableObject mutableFromClosure = sam.retrieveMutable();\n\t\tSystem.out.println(&amp;quot;nmutableFromClosure content = &amp;quot; + mutableFromClosure.getContent());\n\n\t\tMutableObject mutableFromAnonymous = scopingOfThis.createAnonymous().retrieveMutable();\n\t\tSystem.out.println(&amp;quot;mutableFromAnonymous content = &amp;quot; + mutableFromAnonymous.getContent());\n\t\tSystem.out.println(&amp;quot;&amp;quot;);\n\t}\n}\n<\/pre>\n<p> At <strong>line 17<\/strong> in the lambda expression, the this keyword is used to distinguish the class level mutable field from the local mutable (&#8220;from_closure&#8221;) field.<\/p>\n<p> At <strong>line 33<\/strong> in the anonymous class, the <strong>this<\/strong>.<em>mutable<\/em> refers to the mutable field declared in the anonymous class only (<strong>line 27<\/strong>)<\/p>\n<p> Not surprisingly, the output gives<\/p>\n<blockquote><p>\nmutableFromClosure content = <strong>default_content<\/strong><br \/>\nmutableFromAnonymous content = <strong>from_anonymous<\/strong>\n<\/p><\/blockquote>\n<p> Now, what if we declare a local mutable field in the <em>createClosure()<\/em> method before creating the lambda expression ?<\/p>\n<pre class=\"brush: java; highlight: [3,7]; title: ; wrap-lines: false; notranslate\" title=\"\">\n\tpublic VariableCaptureInClosureSAM createClosure()\n\t{\t\n\t\tMutableObject mutable = new MutableObject();\n\t\t\n\t\tVariableCaptureInClosureSAM lambda = ()-&amp;gt;\n\t\t{\t\n\t\t\tMutableObject mutable = new MutableObject();\n\t\t\tmutable.setContent(&amp;quot;from_closure&amp;quot;);\n\t\t\t\n\t\t\treturn this.mutable;\n\t\t};\n\n\t\treturn lambda;\n\t}\n<\/pre>\n<p> The compilation will fail with the error<\/p>\n<blockquote><p>\nScopingOfThis.java:16: error: variable mutable is already defined in method createClosure()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MutableObject <strong>mutable<\/strong> = new MutableObject();<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^\n<\/p><\/blockquote>\n<p> No surprise here. <strong>As in a normal code block you cannot declare a local variable with the same name (the type doesn&#8217;t matter) if it already exists in the current lexical scope<\/strong>.<\/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>ScopingOfThis.bat(ScopingOfThis.sh)<\/strong> script<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h1>II &#8220;Effectively final&#8221; semantic for local variables<\/h1>\n<p> In the JDK 7, variable from enclosing class can be used in anonymous functions only if they are declared <strong>final<\/strong>. With the JDK 8 this constraint has been relaxed <strong>both for lambda expressions and inner classes<\/strong>. It is so called &#8220;<strong>effectively final<\/strong>&#8221; if the variable initial value does not change. But what is the initial value ? It is its reference ? Is it its state ? The litterature is very vague about the fact (<a href=\"http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-state-4.htm\" title=\"http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-state-4.htm\" target=\"_blank\">http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-state-4.htm<\/a> chapter 7)<\/p>\n<p> The best way to clarify it is testing.<\/p>\n<pre class=\"brush: java; highlight: [6,9,12,13]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic class LocalEffectivelyFinalVariable\n{\n\tpublic VariableShadowingSAM retrieveVariableShadowingSAM()\n\t{\n\t\tList&amp;lt;String&amp;gt; textList = new ArrayList&amp;lt;String&amp;gt;();\n\t\ttextList.add(&amp;quot;default&amp;quot;);\n\t\tVariableShadowingSAM sam = () -&amp;gt;\n\t\t{\n\t\t\treturn textList.get(0);\n\t\t};\n\n\t\ttextList.clear();\n\t\ttextList.add(&amp;quot;changed_default&amp;quot;);\n\t\treturn sam;\n\t}\n\n\tpublic static void main(String... args)\n\t{\n\t\tLocalEffectivelyFinalVariable variableShadowing = new LocalEffectivelyFinalVariable();\n\t\tString text = variableShadowing.retrieveVariableShadowingSAM().process();\n\t\tSystem.out.println(&amp;quot;nnttext = &amp;quot; + text);\n\t\tSystem.out.println(&amp;quot;&amp;quot;);\n\n\t}\n}\n<\/pre>\n<p> In the above code, after initializing the list with &#8220;<strong>default<\/strong>&#8221; (<strong>line 6<\/strong>), the lambda expression is created and returns the first element of this list (<strong>line 9<\/strong>).<\/p>\n<p> Right after lambda declaration, the list is cleared and initialized to &#8220;changed_default&#8221; (<strong>lines 12-13<\/strong>).<\/p>\n<p> How is the local &#8220;<strong>effectively final<\/strong>&#8221; <em>textList<\/em> variable captured ? 2 implementations are possible:<\/p>\n<ol>\n<li>either the lambda catures the reference on the returned object, which is the &#8220;<strong>default<\/strong>&#8221; string (<em>testList.get(0)<\/em>). It means that any subsequent change in the <em>textList<\/em> would not affect the returned value at runtime<\/li>\n<li>or the lambda only captures the reference on the <em>textList<\/em> variable and delays <em>get(0)<\/em> invocation at runtime. This second implementation makes the returned value unpredictable since the <em>textList<\/em> can be changed after lambda definition<\/li>\n<\/ol>\n<p> The output displays:<\/p>\n<blockquote><p> text = <strong>changed_default<\/strong><\/p><\/blockquote>\n<p> This result clearly demonstrates that the second implementation has been chosen for JDK 8. <strong>The lambda only keeps the reference on local variable and method invocation is performed at runtime !<\/strong><\/p>\n<p>Now what if we change the reference on the <em>textList<\/em> variable after lambda expression creation ?<\/p>\n<pre class=\"brush: java; title: ; wrap-lines: false; notranslate\" title=\"\">\n\tpublic VariableShadowingSAM retrieveVariableShadowingSAM()\n\t{\n\t\tList&amp;lt;String&amp;gt; textList = new ArrayList&amp;lt;String&amp;gt;();\n\t\ttextList.add(&amp;quot;default&amp;quot;);\n\t\tVariableShadowingSAM sam = () -&amp;gt;\n\t\t{\n\t\t\treturn textList.get(0);\n\t\t};\n\t\ttextList = new ArrayList&amp;lt;String&amp;gt;();\n\t\ttextList.add(&amp;quot;new_instance&amp;quot;);\n\n\t\treturn sam;\n\t}\n<\/pre>\n<p>The output displays:<\/p>\n<blockquote><p> text = <strong>default<\/strong><\/p><\/blockquote>\n<p> This result confirms our previous analysis. The lambda keeps the reference on the old <em>textList<\/em> instance. Even though the local <em>textList<\/em> has been assigned a new instance of ArrayList with a &#8220;<strong>new_instance<\/strong>&#8221; value, the lambda execution at runtime still displays &#8220;<strong>default<\/strong>&#8220;. <\/p>\n<p> <strong><font color=\"red\">This is the true meaning of &#8220;effectively final&#8221;. The lambda capture the reference of your local variable in its declaration. No matter how the variable is assigned a new reference afterward, the old reference is still hold by the lambda. It is as if the variable was declared final in the end.<\/font><\/strong><\/p>\n<p> <strong>It is interesting to compare JDK 8 closure implementation with Javascript implementation<\/strong>. If you&#8217;re familiar with Javascript internals you should know that a closure in Javascript keeps reference to the local variables through <strong>scope chain<\/strong>.<\/p>\n<pre class=\"brush: jscript; highlight: [3,7,10]; title: ; wrap-lines: false; notranslate\" title=\"\">\nfunction getClosure()\n{\n    var text=&amp;quot;default&amp;quot;;\n\n    var closure = function()\n    {\n        return text;\n    }\n\n    text=&amp;quot;changed_default&amp;quot;;\n\n    return closure;\n}\n<\/pre>\n<blockquote><p>\n&gt;getClosure()();<br \/>\n<br \/>\n&gt;&#8221;changed_default&#8221;\n<\/p><\/blockquote>\n<p>At runtime, when the closure is invoked, it will look for the <em>text<\/em> variable in its scope chain. Since the <strong>getClosure <\/strong>function (object) is in the chain, the <em>text<\/em> reference is returned. The displayed value corresponds to the last known value for <em>text<\/em>, which was &#8220;<strong>changed_default<\/strong>&#8220;.<\/p>\n<p> It is very similar to the capture of the <strong>this<\/strong> reference by lambda expression in Java discussed in the previous article.<\/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>LocalEffectivelyFinalVariable.bat(LocalEffectivelyFinalVariable.sh)<\/strong> script<\/p><\/blockquote>\n<p>To be continued &#8230;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this second post, we&#8217;ll look at the scoping of the this keyword inside a lambda expression and the semantic of the so called &#8220;effectively final&#8221; local variables.<\/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\/1347"}],"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=1347"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1347\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}