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

Reply via email to