A possible bug in JEP 482: Flexible Constructor Bodies
Archie Cobbs
archie.cobbs at gmail.com
Mon May 20 22:00:51 UTC 2024
Hi Ella,
Thanks for the report.
First, we can dispense with Case 3 - that program doesn't compile under any
JDK version ("variable x might not have been initialized"), because
initializer blocks run immediately after super(), which in this case is
(implicitly) located at the beginning of the constructor and therefore
prior to the assignment of x.
Having said that, now take a look at Case 2: it has the same problem, but
in a slightly different form.
You can see this by trying to compile this version of Case 2 with the first
constructor removed:
class Q {
final int x;
int y;
{ y = x; }
public Q() {}
}
You get the same error "variable x might not have been initialized".
When you add back the first constructor to get your original Case 2, you
still haven't fixed that problem.
Then the compiler reports this:
Q.java:7: error: variable x might already have been assigned
this();
^
Q.java:4: error: variable x might not have been initialized
{ y = x; }
^
The error reported on line 7 is slightly confusing, but it's really just a
side effect of the error on line 4 that was already present.
In other words, clearly someone could invoke the second constructor Q() and
there would be nothing that initializes field x, so the program is not
valid.
On the other hand, the compiler assumes that the other constructor is going
to properly initialize all final fields when it sees this(), and therefore
it deduces that a duplicate assignment must be occurring. This assumption
is wrong, but only because constructor Q() is invalid.
Here's a version that does compile. Note that it fails if you uncomment the
commented-out line.
class Q {
final int x;
int y;
{ y = x; }
public Q(int a) {
//x = a; // "variable x might already have been assigned"
this();
}
public Q() {
x = 3;
super();
}
}
-Archie
On Mon, May 20, 2024 at 4:13 PM Ella Ananeva <ella.ananeva at oracle.com>
wrote:
> Hi,
>
>
>
> I found a discrepancy in the behavior of the JEP 482 compiler regarding
> definite assignment of a final non-static blank field in a prologue of a
> constructor:
>
> Case 1
>
> Case 2
>
> Case 3
>
> class Q {
> final int x;
> int y;
> { y = x; }
> public Q(int a) {
> x = a;
> super();
>
> }
> }
>
> class Q {
> final int x;
> int y;
> { y = x; }
> public Q(int a) {
> x = a;
> this();
> }
>
> public Q() {}
> }
>
> class Q {
> final int x;
> int y;
> { y = x; }
> public Q(int a) {
> x = a;
> }
> }
>
>
>
> Compilation succeeds
>
> Compilation fails
>
> Compilation fails
>
>
>
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240520/11ce3278/attachment.htm>
More information about the amber-dev
mailing list