<div dir="ltr"><div dir="ltr">Hi Alex,<br></div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> An explicit goal of JEP 447 is **any existing program must compile to<br>
> the same bytecode**. So if we adhere to that goal, local classes<br>
> declared in pre-construction contexts must have outer instances.<br>
I don't see this explicit goal stated in JEP 447. There's a sentence <br>
about compilation in Testing -- "We will compile all JDK classes using <br>
the previous and new versions of the compiler and verify that the <br>
resulting bytecode is identical." -- but that sounds merely like a <br>
nice-to-have property, and one which holds only for JDK classes.<br></blockquote><div><br></div><div>You're right.. the stated goal is actually "Do not change the behavior of any existing program." <br></div><div><br></div><div>Making sure the emitted bytecode matches is just one way to accomplish that goal (and possibly overkill).<br></div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> I think this is the most natural behavior anyway. Anonymous classes,<br>
> with their "immediate enclosing instance with respect to superclass S",<br>
> and their declare-and-instantiate-all-at-once property, are the<br>
> oddballs. It's appropriate for them to have a special rule where their<br>
> implicit outer instance "disappears" in a pre-construction context<br>
> because it would never be possible to provide one.<br>
<br>
I'm not, per se, disagreeing with specifying that local classes declared <br>
in a pre-construction context are inner. It's certainly attractive from <br>
a compatibility POV to be able to move a local class declaration around <br>
within a constructor body (maybe before super(..)/this(..), maybe after) <br>
and observe no class file change because the local class is always inner <br>
(unless it's a local enum class or local record class of course).</blockquote><div><br></div><div>Agreed. </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On the other hand, we have to guarantee that no instantiation of the local <br>
class is possible before super(..)/this(..) has completed normally. <br></blockquote><div><br></div><div>Yes.. and same thing for non-static member classes, so this is not special to local classes.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Don't worry about JEP 401 until JEP 447 has thoroughly clarified the <br>
matter of whether such local classes are inner or not.</div></blockquote><div><br>
</div><div>Thanks - so yes that central question remains... how should we treat local classes in pre-construction contexts?</div><div><br></div><div>The current implementation answers this question "they are inner classes with outer instances just like they would be in any other non-static location".</div><div><br></div><div>Admittedly that answer was chosen in part because it is the most conservative change (in particular, it produces the same bytecode).<br></div><div><br></div><div>But OK let's be a little bolder and ask what would be the BEST change?</div><div><br></div><div>My latest thinking is we should just allow local classes to be declared "static".</div><div><br></div><div>Then "class Local" gives the current behavior (always having an outer instance in a non-static context), while "static class Local" gives the same behavior as a static member class.</div><div><br></div><div>You could then declare AND instantiate a static local class in a pre-construction context - might be handy for doing pre-construction "housekeeping".<br></div><div><br></div><div>Plus, this simplifies a developer's mental model for the various types of classes, because now local classes and member classes are the same, except of course for their lexical location and scope.<br></div><div><br></div><div>This would be the best of both worlds... ?</div></div><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Here's a program that tries to instantiate a Local which observes x with <br>
a value other than 5. What does the JLS say about the program?</blockquote><div><br></div><div>JLS says <span style="font-family:monospace">this()</span><span style="font-family:arial,sans-serif">/</span><span style="font-family:monospace">super()</span> have to be "top level", so they can't be inside a <span style="font-family:monospace">try { }</span> block.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">What does javac do?<br></blockquote><br></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace">Test.java:10: error: switch expression does not have any result expressions<br>             this(switch (0) { default -> throw new Exception(); });<br>                  ^<br>Test.java:12: error: cannot reference this before supertype constructor has been called<br>             new Local();  // Legal or illegal?<br>             ^<br>Test.java:10: error: calls to this() not allowed here<br>             this(switch (0) { default -> throw new Exception(); });<br>                 ^<br>3 errors</span></div><div class="gmail_quote"><br></div><div class="gmail_quote">(The first error can be worked around by inserting <span style="font-family:monospace">case 1 -> 2;</span> of course).<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">-Archie<br></div><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature">Archie L. Cobbs<br></div></div>