My sense is that the spec got a little over-zealous calling the
preamable of a constructor a "static context". This was accurate prior
to generics, but no longer accurate when class type variables are
involved because constructors are instance "members".
The logical fix IMO is to sever the link to "static context" in 8.8.7.
Currently it says:
An explicit constructor invocation statement introduces a static
context (§8.1.3),
which limits the use of constructs that refer to the current object.
Notably, the
keywords this and super are prohibited in a static context (§15.8.3,
§15.11.2),
as are unqualified references to instance variables, instance methods,
and type
parameters of lexically enclosing declarations (§6.5.5.1, §6.5.6.1,
§15.12.3).
This can be amended to:
An explicit constructor invocation statement introduces an
_pre-initialization context_, which limits the use of constructs that
refer to the current object. Notably, the keywords `this` and `super`
are prohibited in a pre-initialization context, as are unqualified
references to instance variables and instance methods of lexically
enclosing declarations.
Then static context still means what it means, we are just being honest
that the preamble of a constructor body is something different, and we
spell out the restrictions of what that means directly in 8.8.7.
On 2/2/2023 3:09 PM, Archie Cobbs wrote:
On Tue, Jan 31, 2023 at 2:45 PM Archie Cobbs <[email protected]>
wrote:
Obviously this change requires a JEP, and so we have this JEP
draft for review:
JDK-8300786 <https://bugs.openjdk.org/browse/JDK-8300786> - No
longer require super() and this() to appear first in a constructor
Update on this JEP.
Doing a little more research I discovered that since Java 8 the
compiler has not been following the spec as it applies to allowing
type parameters inside super() calls (bug filed as JDK-8301649
<https://bugs.openjdk.org/browse/JDK-8301649>).
The spec says this is a "static context", so type parameters are in
theory not allowed. But the compiler allows it, and in fact it seems
the spec is being too restrictive.
With the change in this JEP, this discrepancy will only get worse,
because the "static context" that's part of a constructor can now
include a lot more stuff.
In this discussion on compiler-dev
<https://mail.openjdk.org/pipermail/compiler-dev/2023-February/021960.html>
it was generally agreed that the spec should probably be fixed as part
of this JEP.
So I'm wondering about people's thoughts on this list - not only
whether to fix the spec, but also how exactly to do so, any other
suggestions, etc.
I see two options:
1. Split "static context" in two:
1. The old "static context" gets renamed to "lexically static
context". References to anything non-static are disallowed -
same as now.
2. Define a new "referentially static context" which disallows
any references to 'this' (explicit or implicit) but allows
type parameters, etc.
2. Leave "static context" alone, but add an exception to how it
applies prior to super() so that it permits type parameters, etc.
Or maybe there is another option... ?
Thoughts?
Thanks,
-Archie
--
Archie L. Cobbs