Loosening requirements for super() invocation
Brian Goetz
brian.goetz at oracle.com
Mon Jan 30 14:49:43 UTC 2023
This is a first stab, but I think this may be the extent of the spec
changes for this JEP:
> 8.8.7 Constructor Body
> The first statement of a constructor body may be an explicit
> invocation of another
> constructor of the same class or of the direct superclass (§8.8.7.1).
A constructor body _may contain_ an explicit invocation...
> ConstructorBody:
> { [ExplicitConstructorInvocation] [BlockStatements] }
ConstructorBody:
{ [BlockStatements] [ExplicitConstructorInvocation] [BlockStatements] }
> It is a compile-time error for a constructor to directly or indirectly
> invoke itself
> through a series of one or more explicit constructor invocations
> involving this.
> If a constructor body does not begin with an explicit constructor
> invocation and
does not contain an explicit constructor invocation
> the constructor being declared is not part of the primordial class
> Object, then
> the constructor body implicitly begins with a superclass constructor
> invocation
> "super();", an invocation of the constructor of its direct superclass
> that takes no
> arguments.
> Except for the possibility of explicit constructor invocations, and
> the prohibition
> on explicitly returning a value (§14.17), the body of a constructor is
> like the body
> of a method (§8.4.7).
> A return statement (§14.17) may be used in the body of a constructor
> if it does
> not include an expression.
If a constructor body contains an explicit constructor invocation, the
BlockStatements preceding the explicit constructor invocation are called
the _prologue_ of the constructor body, and the BlockStatements
following the explicit constructor invocation are called the _main body_
of the constructor. A return statement may be used in the main body of
a constructor if it does not include an expression. It is a
compile-time error if a return statement appears in the prologue of the
constructor body.
> 8.8.7.1 Explicit Constructor Invocations
> An explicit constructor invocation statement introduces a static
> context (§8.1.3),
which includes the prologue of the constructor and the explicit
constructor invocation statement,
> 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).
Additionally, as you point out, there are some corresponding changes in
12.5. Your list is a good start, I'd amplify as:
> 1. If this constructor contains an explicit constructor invocation
> (§8.8.7.1), then execute the preceding |BlockStatements|, if any.
>
If this constructor contains an explicit constructor invocation, then
execute the BlockStatements of the prologue of the constructor body. If
execution of any statement completes abruptly, then execution of the
constructor completes abruptly for the same reason.
On 1/28/2023 11:03 AM, Archie Cobbs wrote:
> On Fri, Jan 27, 2023 at 8:19 PM John Rose <john.r.rose at oracle.com> wrote:
>
> On 26 Jan 2023, at 11:19, Maurizio Cimadamore wrote:
>
> On 26/01/2023 18:16, Archie Cobbs wrote:
>
> Yes, but for this to happen the subclass would have to be
> in effect intentionally subverting the superclass constructor.
>
> In other words, a problem like you describe can't suddenly
> just start happening "by accident" just because this new
> feature exists...
>
> Well, you could have a subclass (in some client jar) which
> "subverts" as you say, some superclass in a library. Perhaps
> the library was not prepared for that kind of behavior, and
> now there's a new bug.
>
> IMHO, we should try to stay well clear of that can of worms.
> It's not like we have to open it now either - the other things
> you propose are 100% non-controversial.
>
> Just to be clear:
>
> Early assignment to a /super/ field is never possible
>
>
> Ah, you are correct. I was missing this nuance and incorrectly
> thinking it was allowed to write to *any* field in the object prior to
> super().
>
> JVMS §4.10.2.4
> <https://urldefense.com/v3/__http://4.10.2.4__;!!ACWV5N9M2RV99hQ!PVfZ2aP1yhsmDre2rqLZwvzdU2KqHPHxwcf19bfGgyqPIZCOpSjLpImKZbP3917Y2zJtbWyCr5rKOTzGy6Ammew$>:
>
> Before that method invokes another instance initialization method
> of |myClass| or its direct superclass on |this|, the only
> operation the method can perform on |this| is assigning fields
> *declared within |myClass|*.
>
>
> So that whole discussion about writing to superclass fields prior to
> super() is moot.
>
> I must be missing your point here Maurizio… There is
> some corner case you are concerned with but I can’t see
> where the danger is.
>
>
> Yes... and now me too :)
>
> -Archie
>
> --
> Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20230130/4ff06d54/attachment-0001.htm>
More information about the amber-dev
mailing list