<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
> If we have a lambda as a local variable in the constructor, it cannot be invoked outside of the constructor, right?</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
It actually can. In fact, lambdas are just like any objects: wherever the object is accessible, its public methods are accessible, so the lambda can be invoked outside of the constructor if it's passed somewhere else, such as being stored in an instance (non-static)
 field.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
As a result, for now, if you know you executed another method that takes a lambda (like ClassFile.build()) and that lambda is executed, the best bet for you is to declare an array like:</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
int[] value = new int[0]; // uses a mutable object (here a length-1 array) to capture value</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
api.execute(arguments, lambdaArg -> { value[0] = lambdaArg; });</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
this.earlyField = value[0]; // maybe add checks to ensure value is properly initialized</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
If we just allow assignment to early field in a lambda, it's possible for api to send this lambda into an executor that calls the lambda with 5 second delay; that scenario is clearly not "early-construction context" and the language rule aims to prevent such
 misuse.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
- Chen</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Ella Ananeva <ella.ananeva@oracle.com><br>
<b>Sent:</b> Wednesday, June 5, 2024 4:29 PM<br>
<b>To:</b> Chen Liang <chen.l.liang@oracle.com>; amber-dev <amber-dev@openjdk.org><br>
<b>Subject:</b> Re: [External] : Re: This expression in lambda in early construction context</font>
<div> </div>
</div>
<style>
<!--
@font-face
        {font-family:Helvetica}
@font-face
        {font-family:"Cambria Math"}
@font-face
        {font-family:Calibri}
@font-face
        {font-family:Aptos}
p.x_MsoNormal, li.x_MsoNormal, div.x_MsoNormal
        {margin:0in;
        font-size:12.0pt;
        font-family:"Aptos",sans-serif}
p.x_xmsonormal, li.x_xmsonormal, div.x_xmsonormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Aptos",sans-serif}
span.x_EmailStyle22
        {font-family:"Aptos",sans-serif;
        color:windowtext}
.x_MsoChpDefault
        {font-size:10.0pt}
@page WordSection1
        {margin:1.0in 1.0in 1.0in 1.0in}
div.x_WordSection1
        {}
-->
</style>
<div lang="EN-US" link="#467886" vlink="#96607D" style="word-wrap:break-word">
<div class="x_WordSection1">
<p class="x_MsoNormal"><span style="font-size:11.0pt">Thanks for pointing this out, Chen.</span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt">Please bear with me for a moment. If we have a lambda as a local variable in the constructor, it cannot be invoked outside of the constructor, right?
</span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal" style="background:white"><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">class
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:black">Main
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">{<br>
    </span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">int
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#871094">a</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">;<br>
    </span><span style="font-size:10.0pt; font-family:"Courier New"; color:#00627A">Main</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">() {<br>
        </span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">this</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">.a =
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#1750EB">1</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">; //</span><i><span style="font-size:10.0pt; font-family:"Courier New"; color:#8C8C8C">line A<br>
        </span></i><span style="font-size:10.0pt; font-family:"Courier New"; color:black">Foo lmb
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">= () ->
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">this</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">.a =
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#1750EB">1</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">;</span><i><span style="font-size:10.0pt; font-family:"Courier New"; color:#8C8C8C">       
</span></i></p>
<p class="x_MsoNormal" style="background:white"><i><span style="font-size:10.0pt; font-family:"Courier New"; color:#8C8C8C">        </span></i><span style="font-size:10.0pt; font-family:"Courier New"; color:black">lmb</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">.foo();
 //line B<br>
        </span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">super</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">();<br>
    }</span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt">The statement in line A assigns a value to a member field before the superconstructor call.</span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt">Lambda also assigns the value to a field and is invoked before the superconstructor call.  </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt">I’d say the difference in this behavior makes sense only if the compiler doesn’t attempt to initialize the field in line A but tries to initialize it when the lambda is invoked. It’s like line A is just
 an instruction for later, and in line B a real initialization attempt takes place.</span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt">Is this what is happening?</span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<p class="x_MsoNormal"><span style="font-size:11.0pt"> </span></p>
<div id="x_mail-editor-reference-message-container">
<div>
<div style="border:none; border-top:solid #B5C4DF 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal" style="margin-bottom:12.0pt"><b><span style="color:black">From:
</span></b><span style="color:black">Chen Liang <chen.l.liang@oracle.com><br>
<b>Date: </b>Wednesday, June 5, 2024 at 1:43</span><span style="font-family:"Arial",sans-serif; color:black"> </span><span style="color:black">PM<br>
<b>To: </b>Ella Ananeva <ella.ananeva@oracle.com>, amber-dev <amber-dev@openjdk.org><br>
<b>Subject: </b>Re: [External] : Re: This expression in lambda in early construction context</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="color:black">Hi Ella,</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="color:black">What do you mean by "Why should the rules for a lambda be different"? Lambda bodies are not part of the early-construction context, as the lambda can be invoked anywhere and anytime after it's created, including
 before the super constructor call completes (such as when it's passed as a parameter to super constructor).</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="color:black">Best,</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="color:black">Chen</span></p>
</div>
<div class="x_MsoNormal" align="center" style="text-align:center">
<hr size="0" width="98%" align="center">
</div>
<div id="x_divRplyFwdMsg">
<p class="x_MsoNormal"><b><span style="font-size:11.0pt; font-family:"Calibri",sans-serif; color:black">From:</span></b><span style="font-size:11.0pt; font-family:"Calibri",sans-serif; color:black"> amber-dev <amber-dev-retn@openjdk.org> on behalf of Ella Ananeva
 <ella.ananeva@oracle.com><br>
<b>Sent:</b> Wednesday, June 5, 2024 3:30 PM<br>
<b>To:</b> Remi Forax <forax@univ-mlv.fr>; amber-dev <amber-dev@openjdk.org><br>
<b>Subject:</b> Re: [External] : Re: This expression in lambda in early construction context</span>
</p>
<div>
<p class="x_MsoNormal"> </p>
</div>
</div>
<div>
<div>
<p class="x_xmsonormal">Hi Remi,</p>
<p class="x_xmsonormal"> </p>
<p class="x_xmsonormal">Good point! I get it that the value of this is not accessible in lambda body before the superconstructor call.</p>
<p class="x_xmsonormal">However, we cannot access the value of this in the early construction context even without lambda:</p>
<p class="x_xmsonormal"> </p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">class Test {</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">    int a;</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">    Test() {</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">        this.a = 1;</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">        int a = this.a; // compilation error</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">        super();</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">    }</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">}</span></p>
<p class="x_xmsonormal"> </p>
<p class="x_xmsonormal">JEP 482 specifically says that in the early construction context the value of this is not accessible, that we only can assigned the value to the fields of this class. Why should the rules for a lambda be different? I’d say, if we want
 a special behavior for lambda, it should be described in the specification, shouldn’t it?</p>
<p class="x_xmsonormal"> </p>
<p class="x_xmsonormal">Thanks,</p>
<p class="x_xmsonormal">Ella</p>
<p class="x_xmsonormal"> </p>
<div id="x_x_mail-editor-reference-message-container">
<div>
<div style="border:none; border-top:solid #B5C4DF 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_xmsonormal" style="margin-bottom:12.0pt"><b><span style="color:black">From:
</span></b><span style="color:black">Remi Forax <forax@univ-mlv.fr><br>
<b>Date: </b>Wednesday, June 5, 2024 at 12:33</span><span style="font-family:"Arial",sans-serif; color:black"> </span><span style="color:black">PM<br>
<b>To: </b>Ella Ananeva <ella.ananeva@oracle.com><br>
<b>Cc: </b>amber-dev <amber-dev@openjdk.org><br>
<b>Subject: </b>[External] : Re: This expression in lambda in early construction context</span></p>
</div>
<div>
<div>
<p class="x_xmsonormal"><span style="font-family:"Arial",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_xmsonormal"><span style="font-family:"Arial",sans-serif; color:black"> </span></p>
</div>
<div class="x_MsoNormal" align="center" style="text-align:center"><span style="font-size:11.0pt; font-family:"Arial",sans-serif; color:black">
<hr size="0" width="100%" align="center">
</span></div>
<div>
<blockquote style="border:none; border-left:solid #1010FF 1.5pt; padding:0in 0in 0in 4.0pt; margin-left:3.75pt; margin-top:5.0pt; margin-bottom:5.0pt">
<p class="x_xmsonormal"><b><span style="font-family:Helvetica; color:black">From:
</span></b><span style="font-family:Helvetica; color:black">"Ella Ananeva" <ella.ananeva@oracle.com><br>
<b>To: </b>"amber-dev" <amber-dev@openjdk.org><br>
<b>Sent: </b>Wednesday, June 5, 2024 8:45:57 PM<br>
<b>Subject: </b>This expression in lambda in early construction context</span></p>
</blockquote>
</div>
<div>
<blockquote style="border:none; border-left:solid #1010FF 1.5pt; padding:0in 0in 0in 4.0pt; margin-left:3.75pt; margin-top:5.0pt; margin-bottom:5.0pt">
<div>
<p class="x_xmsonormal"><span style="color:black">Hi,</span></p>
<p class="x_xmsonormal"><span style="color:black">I understand that JEP 482 allows to refer to
</span><span style="font-family:"Courier New"; color:black">this</span><span style="color:black"> in the early construction context if this expression is in the left part of an assignment expression:</span></p>
<p class="x_xmsonormal"><span style="color:black"> </span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">class Test {</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">    int a;</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">    Test() {</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">        this.a = 1;</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">        super();</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">    }</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">}</span></p>
<p class="x_xmsonormal"><span style="color:black">This compiles just fine (I have JDK 23 build 25).</span></p>
<p class="x_xmsonormal"><span style="color:black">However, when I try to do the same in a lambda body, I get a compilation error:</span></p>
<p class="x_xmsonormal" style="background:white"><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">interface
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:black">Foo
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">{<br>
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">void
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#00627A">foo</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">();<br>
}<br>
<br>
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">class
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:black">Test
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">{<br>
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">int
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#871094">a</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">;<br>
<br>
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#00627A">Test</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">() {<br>
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:black">Foo lmb
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">= () -> {
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">this</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">.a =
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#1750EB">1</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">;};<br>
</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#0033B3">super</span><span style="font-size:10.0pt; font-family:"Courier New"; color:#080808">();<br>
    }<br>
}</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">Test.java:9:27</span></p>
<p class="x_xmsonormal"><span style="font-family:"Courier New"; color:black">java: cannot reference this before supertype constructor has been called</span></p>
<p class="x_xmsonormal"><span style="color:black">Is lambda body some special case?
</span></p>
</div>
</blockquote>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black">The lambda capture "this" (it is a parameter of the call to the construction of the lambda), but "this" as a value is only available after the call to the super
 constructor.</span></p>
</div>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black"> </span></p>
</div>
<blockquote style="border:none; border-left:solid #1010FF 1.5pt; padding:0in 0in 0in 4.0pt; margin-left:3.75pt; margin-top:5.0pt; margin-bottom:5.0pt">
<div>
<p class="x_xmsonormal"><span style="color:black"> </span></p>
<p class="x_xmsonormal"><span style="color:black">Thank you,</span></p>
<p class="x_xmsonormal"><span style="color:black">Ella Ananeva</span></p>
</div>
</blockquote>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black">regards,</span></p>
</div>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black">Rémi</span></p>
</div>
<div>
<p class="x_xmsonormal"><span style="font-size:12.0pt; font-family:"Arial",sans-serif; color:black"> </span></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>