Field initialization before 'super'

Archie Cobbs archie.cobbs at gmail.com
Wed Dec 13 16:29:27 UTC 2023


On Wed, Dec 13, 2023 at 10:02 AM Remi Forax <forax at univ-mlv.fr> wrote:

> > No such restriction is needed for non-final fields; but it's an open
> question
> > whether we should prohibit all writes before 'this()' anyway.
>
> I would say, keep that restriction.
>

I tend to agree. One benefit would be it creates more separation between
final fields and non-final fields, which would help encourage people to
make fields final so they get all the benefits.


> > Writes to non-final fields with initializers are disallowed, to avoid
> confusion
> > about sequencing (the field initializer will always run later,
> overwriting
> > whatever you put in the constructor prologue.)
>
> This seems to suggest that final fields with initializer should be written
> before the call to super() by default even if it's not a backward
> compatible change.
>

That could only work if the initializer doesn't read "this"... which means
only some initializers would qualify, which would be confusing.


> captured fields in lambda are like strict but captured fields is inner
> classes are like normal fields.
>

I was curious why this would be true and it appears it's not true, at least
from this test:

$ cat Test.java
public class Test {
    public Test(String x) {
        new Runnable() {
            @Override
            public void run() {
                System.out.println(x);
            }
        }.run();
    }
}
$ javap -c -classpath classes Test\$1
Compiled from "Test.java"
class Test$1 implements java.lang.Runnable {
  final java.lang.String val$x;

  Test$1();
    Code:
       0: aload_0
       1: aload_2
       2: putfield      #1                  // Field
val$x:Ljava/lang/String;
       5: aload_0
       6: invokespecial #7                  // Method
java/lang/Object."<init>":()V
       9: return
...

You can see in the Test$1 constructor Test$1.x is being initialized prior
to super().

> - Can I have my implicit 'super()' call go at the end of my constructor?
>

My opinion is also "no" on this question... but because it would add
another logical fork in developers' minds for too little benefit. It's easy
enough to just put it in there explicitly.

-Archie

-- 
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20231213/a985af71/attachment.htm>


More information about the amber-spec-observers mailing list