RFR: 8194743: Compiler implementation for Statements before super() [v14]
Archie Cobbs
archie.cobbs at gmail.com
Mon Sep 25 17:13:10 UTC 2023
Hi Alex,
> > An explicit goal of JEP 447 is **any existing program must compile to
> > the same bytecode**. So if we adhere to that goal, local classes
> > declared in pre-construction contexts must have outer instances.
> I don't see this explicit goal stated in JEP 447. There's a sentence
> about compilation in Testing -- "We will compile all JDK classes using
> the previous and new versions of the compiler and verify that the
> resulting bytecode is identical." -- but that sounds merely like a
> nice-to-have property, and one which holds only for JDK classes.
>
You're right.. the stated goal is actually "Do not change the behavior of
any existing program."
Making sure the emitted bytecode matches is just one way to accomplish that
goal (and possibly overkill).
> I think this is the most natural behavior anyway. Anonymous classes,
> > with their "immediate enclosing instance with respect to superclass S",
> > and their declare-and-instantiate-all-at-once property, are the
> > oddballs. It's appropriate for them to have a special rule where their
> > implicit outer instance "disappears" in a pre-construction context
> > because it would never be possible to provide one.
>
> I'm not, per se, disagreeing with specifying that local classes declared
> in a pre-construction context are inner. It's certainly attractive from
> a compatibility POV to be able to move a local class declaration around
> within a constructor body (maybe before super(..)/this(..), maybe after)
> and observe no class file change because the local class is always inner
> (unless it's a local enum class or local record class of course).
Agreed.
> On the other hand, we have to guarantee that no instantiation of the local
> class is possible before super(..)/this(..) has completed normally.
>
Yes.. and same thing for non-static member classes, so this is not special
to local classes.
Don't worry about JEP 401 until JEP 447 has thoroughly clarified the
> matter of whether such local classes are inner or not.
>
Thanks - so yes that central question remains... how should we treat local
classes in pre-construction contexts?
The current implementation answers this question "they are inner classes
with outer instances just like they would be in any other non-static
location".
Admittedly that answer was chosen in part because it is the most
conservative change (in particular, it produces the same bytecode).
But OK let's be a little bolder and ask what would be the BEST change?
My latest thinking is we should just allow local classes to be declared
"static".
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.
You could then declare AND instantiate a static local class in a
pre-construction context - might be handy for doing pre-construction
"housekeeping".
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.
This would be the best of both worlds... ?
Here's a program that tries to instantiate a Local which observes x with
> a value other than 5. What does the JLS say about the program?
JLS says this()/super() have to be "top level", so they can't be inside a try
{ } block.
> What does javac do?
>
Test.java:10: error: switch expression does not have any result expressions
this(switch (0) { default -> throw new Exception(); });
^
Test.java:12: error: cannot reference this before supertype constructor has
been called
new Local(); // Legal or illegal?
^
Test.java:10: error: calls to this() not allowed here
this(switch (0) { default -> throw new Exception(); });
^
3 errors
(The first error can be worked around by inserting case 1 -> 2; of course).
-Archie
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230925/4f24a1d2/attachment-0001.htm>
More information about the compiler-dev
mailing list