{"id":1353,"date":"2012-07-17T21:03:07","date_gmt":"2012-07-17T19:03:07","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=1353"},"modified":"2015-01-31T13:14:19","modified_gmt":"2015-01-31T13:14:19","slug":"java-8-lambda-in-details-part-v-functional-interface-definition-and-lambda-expression-implementation","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=1353","title":{"rendered":"Java 8 Lambda in details part V : Functional interface definition and lambda expression implementation"},"content":{"rendered":"<p>In this last post we&#8217;ll look at the functional interface formal definition and the way lambda expressions are implemented.<\/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<p>&nbsp;<\/p>\n<h1>I Functional interface definition<\/h1>\n<p> It seems weird to give a definition of a functional interface (aka SAM interface) in the last post but the truth is that I discover the subtle semantic of functional interface only recently.<\/p>\n<p> Usually people naively think that a functional interface must contain only one single abstract method. The real definition is less restrictive indeed. <\/p>\n<blockquote><p><strong>An interface is considered a functional interface if it contains one and only one abstract method with no default implementation<\/strong><\/p><\/blockquote>\n<p>No assertion is made about the possibility for this interface to declare static fields or many defenders methods. It means that a functional interface can<\/p>\n<ol>\n<li>have one abstract method and many defenders methods and static fields<\/li>\n<li>have one abstract method and inherit defenders from parent interfaces and static fields<\/li>\n<\/ol>\n<p>The implication of these subtle details is huge indeed. <font color=\"red\"><strong>We can have lambda expressions with default behaviors embedded (via defender methods)!<\/strong><\/font><\/p>\n<p> The code example in the next chapter will prove it.<\/p>\n<p>&nbsp;<\/p>\n<h1>II Lambda expression implementation<\/h1>\n<p> Did you ever wonder how the JDK 8 implements an lambda expression ? The following <a href=\"http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-translation.html\" title=\"http:\/\/cr.openjdk.java.net\/~briangoetz\/lambda\/lambda-translation.html\" target=\"_blank\">article<\/a> gives us some insights.<\/p>\n<p>Basically, the compiler will create anonymous inner classes to emulate the functioning of lambda expressions. Two possible scenarios there:<\/p>\n<ol>\n<li>the lambda expression is stateless and does not capture any variable: an <strong>anonymous inner class<\/strong> is created with a no argument constructor<\/li>\n<li>the lambda expression does capture variables (this or local variable): <strong>they are injected through anonymous inner class constructor as parameters<\/strong><\/li>\n<\/ol>\n<p>Let consider the following sample:<\/p>\n<pre class=\"brush: java; highlight: [5]; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic interface SAMWithDefender\r\n{\r\n\tString staticvar = &quot;static var in SAM&quot;;\r\n\t\r\n\tvoid test();\r\n\t\r\n\tvoid whoAmI() default \r\n\t{\r\n\t\tSystem.out.println(&quot;I am &quot;+this);\r\n\t}\r\n}\r\n\r\npublic class LambdaInstance\r\n{\r\n\r\n\tpublic static SAMWithDefender createLambda()\r\n\t{\r\n\t\treturn () -&gt; {System.out.println(&quot;&quot;);};\r\n\t}\r\n\r\n\tpublic static SAMWithDefender createStatefullLambda(String input)\r\n\t{\r\n\t\treturn () -&gt; {System.out.println(&quot;input = &quot;+input);};\r\n\t}\r\n\r\n\tpublic static void main(String[] args)\r\n\t{\r\n\t\tSAMWithDefender samInstance1 = LambdaInstance.createLambda();\r\n\t\tSAMWithDefender samInstance2 = LambdaInstance.createStatefullLambda(&quot;statefull&quot;);\r\n\r\n\t\tSystem.out.println(&quot;\\n&quot;);\r\n\t\tsamInstance1.whoAmI();\r\n\t\tsamInstance2.whoAmI();\r\n\t\tSystem.out.println(&quot;&quot;);\r\n\t}\r\n}\r\n\r\n<\/pre>\n<p> We define an interface with a static field and 2 methods. One of them is provided a default implementation, the other is let abstract (<strong>line 5<\/strong>). This interface meets the requirement to be a functional interface (one single abstract method) as mentioned in the previous chapter.<\/p>\n<p> In the main class, we define 2 lambda expressions, one stateless (<strong>line 28<\/strong>) and one capturing local variable (<strong>line 29<\/strong>).<\/p>\n<p> I compile the class and use the &#8220;<strong>javap -verbose<\/strong>&#8221; command to examine the generated bytecode.<\/p>\n<p> Definition of <strong>fr.doan.lambda.instance.LambdaInstance<\/strong> class:<\/p>\n<pre class=\"brush: java; highlight: [16,18,27,30]; title: ; wrap-lines: false; notranslate\" title=\"\">\r\n{\r\n  public fr.doan.lambda.instance.LambdaInstance();\r\n    flags: ACC_PUBLIC\r\n    Code:\r\n      stack=1, locals=1, args_size=1\r\n         0: aload_0\r\n         1: invokespecial #1                  \/\/ Method java\/lang\/Object.&quot;&lt;init&gt;&quot;:()V\r\n         4: return\r\n      LineNumberTable:\r\n        line 5: 0\r\n\r\n  public static fr.doan.lambda.sam.instance.SAMWithDefender createLambda();\r\n    flags: ACC_PUBLIC, ACC_STATIC\r\n    Code:\r\n      stack=2, locals=0, args_size=0\r\n         0: new           #2                  \/\/ class fr\/doan\/lambda\/instance\/LambdaInstance$1\r\n         3: dup\r\n         4: invokespecial #3                  \/\/ Method fr\/doan\/lambda\/instance\/LambdaInstance$1.&quot;&lt;init&gt;&quot;:()V\r\n         7: areturn\r\n      LineNumberTable:\r\n        line 10: 0\r\n\r\n  public static fr.doan.lambda.sam.instance.SAMWithDefender createStatefullLambda(java.lang.String);\r\n    flags: ACC_PUBLIC, ACC_STATIC\r\n    Code:\r\n      stack=3, locals=1, args_size=1\r\n         0: new           #4                  \/\/ class fr\/doan\/lambda\/instance\/LambdaInstance$2\r\n         3: dup\r\n         4: aload_0\r\n         5: invokespecial #5                  \/\/ Method fr\/doan\/lambda\/instance\/LambdaInstance$2.&quot;&lt;init&gt;&quot;:(Ljava\/lang\/String;)V\r\n         8: areturn\r\n      LineNumberTable:\r\n        line 15: 0 \r\n}\r\n<\/pre>\n<p> At <strong>lines 16 &amp; 18<\/strong>, the static method <em>createLambda()<\/em> is instanciating a new anonymous inner class  &#8220;<strong>fr\/doan\/lambda\/instance\/LambdaInstance$1<\/strong>&#8221; with no argument constructor.<\/p>\n<p>  At <strong>lines 27 &amp; 30<\/strong>, the static method<em> createStatefullLambda()<\/em> is instanciating a new anonymous inner class  &#8220;<strong>fr\/doan\/lambda\/instance\/LambdaInstance$2<\/strong>&#8221; with the captured method parameter as constructor argument.<\/p>\n<p> Let&#8217;s decompile the anonymous inner class  &#8220;<strong>fr\/doan\/lambda\/instance\/LambdaInstance$2<\/strong>&#8221;<\/p>\n<pre class=\"brush: java; highlight: [7,8,10]; title: ; wrap-lines: false; notranslate\" title=\"\">\r\n{\r\nclass fr.doan.lambda.instance.LambdaInstance$2 implements fr.doan.lambda.sam.instance.SAMWithDefender\r\n  SourceFile: &quot;LambdaInstance.java&quot;\r\n  EnclosingMethod: #24.#25                \/\/ fr.doan.lambda.instance.LambdaInstance.createStatefullLambda\r\n  InnerClasses:   static #10; \/\/class fr\/doan\/lambda\/instance\/LambdaInstance$2\r\n\t   \r\n  java.lang.String cap$0;\r\n    flags: ACC_SYNTHETIC\r\n\r\n  fr.doan.lambda.instance.LambdaInstance$2(java.lang.String);\r\n    flags:\r\n    Code:\r\n      stack=2, locals=2, args_size=2\r\n         0: aload_0\r\n         1: invokespecial #1                  \/\/ Method java\/lang\/Object.&quot;&lt;init&gt;&quot;:()V\r\n         4: aload_0\r\n         5: aload_1\r\n         6: putfield      #2                  \/\/ Field cap$0:Ljava\/lang\/String;\r\n         9: return\r\n      LineNumberTable:\r\n        line 15: 0\r\n      ...\r\n      ...\r\n}\r\n<\/pre>\n<p> We clearly see at <strong>lines 7-8<\/strong> that the compiler generated a synthetic field <strong>cap$0<\/strong> (capture0) to capture the local variable and passed it to the constructor argument (<strong>line 10<\/strong>)<\/p>\n<p> When executing the LambdaInstance class, the output shows:<\/p>\n<blockquote><p>\nI am fr.doan.lambda.instance.<strong>LambdaInstance$1<\/strong>@59dbd<br \/>\n<br \/>\nI am fr.doan.lambda.instance.<strong>LambdaInstance$2<\/strong>@b6e768\n<\/p><\/blockquote>\n<p> That&#8217;s all folks!<\/p>\n<p>&nbsp;<\/p>\n<blockquote><p>The above scenario can be illustrated by a code example 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 LambdaInstance.bat(LambdaInstance.sh) script<\/p><\/blockquote>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this last post we&#8217;ll look at the functional interface formal definition and the way lambda expressions are implemented.<\/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\/1353"}],"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=1353"}],"version-history":[{"count":1,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1353\/revisions"}],"predecessor-version":[{"id":1754,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1353\/revisions\/1754"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}