> From: "Archie Cobbs" <[email protected]>
> To: "Remi Forax" <[email protected]>
> Cc: "daniel smith" <[email protected]>, "amber-spec-experts"
> <[email protected]>
> Sent: Wednesday, December 13, 2023 5:29:27 PM
> Subject: Re: Field initialization before 'super'

> On Wed, Dec 13, 2023 at 10:02 AM Remi Forax < [ mailto:[email protected] |
> [email protected] ] > 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.

yes, 

>> 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().

Yes, but you can still change the value of the field by reflection, unlike with 
the fields of a lambda proxy, so the field containing the captured value is not 
strict. 

>> > - 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.

What we are trying to do here, is to follow Dan's idea that there is no need 
for an additional keyword and that the compiler can infer the strictness by 
itself. 
As you said, the problem of that idea is that the developer is not really in 
control, subtle changes like the initializer depending on 'this' make the final 
field strict or not. 

> -Archie

regards, 
Rémi 

> --
> Archie L. Cobbs

Reply via email to