Bug in javac and eclipse ??

Remi Forax forax at univ-mlv.fr
Tue Jan 21 15:46:43 PST 2014


On 01/22/2014 12:14 AM, Dan Smith wrote:
> The relevant spec (unchanged by Lambda) is 8.3.3.  The error is as specified.
>
> This has been on the radar for a few months, with emails about it popping up periodically.  See, e.g, the "Reader mail bag, 2nd edition" email:
>
>> 3 Dec 2013, Markus Keller <markus_keller at ch.ibm.com>, "Self-reference to field from lambda expression in initializer"
>> I've had quite a few discussions about this, and concluded that it is best not to do anything until we flesh out a potential "recursive lambda expression" feature in the future.  (In 8, local variables initialized with lambdas have a similar inability to directly refer to themselves.)
> Adding to that conclusion a bit:
>
> - It is sometimes safe to refer to field inside a lambda in its initializer body, but not always (e.g., what if you immediately invoke a lambda in the initializer?)

You may see the wrong value (at least not the one you expect) but it's 
clearly not unsafe or we have not the same definition of unsafe.

The issue you describe may appear with an anonymous class too (so since 
Java 1.1), but this code is legal:
class Foo {
   A field = new A(new Runnable() {
     @Override
     public void run() {
       System.out.println(field);
     }
   });
}

To sumarrize, I don't understand:
  1) why the code is valid for an anonymous class but not a lambda ?
  2) why the type checker rejects a perfectly valid code. ?
  3) why qualified access works but not unqualified access doesn't ?

>
> - Were we to come up with a perfect rule, the rules for when it's safe to refer to a field would be the same as the rules for when it's safe to refer to a local variable.  (Noting, however, that the requirements of the language are different: it is never tolerable to refer to a local variable before initialization, while early access to fields is sometimes permitted.)

yes, it's permitted when the code may work.

>
> - The approach we took in JSR 335 in general was to claim that recursive lambdas were probably not all that useful, and wait for evidence to the contrary.  An argument for more convenient recursive access in field initializers is probably also an argument for support for recursive access from local variable initializers.

no, as you said in the sentence just above, before 8, reference to 
fields were accepted by the JLS when it can be meaningful, reference to 
local variable are never accepted.

>
> - In any case, you can always use qualified access ('System.out.println(ReferenceProblem.constant)'), for which 8.3.3 does not apply.

see the question of Sam, it's confusing when unqualified access doesn't 
work but qualified access work.

It's like created an artificial corner case without

>
> —Dan

regards,
Rémi

>
> On Jan 21, 2014, at 3:23 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>
>> (CC lambda-dev)
>> This code do not compile neither with Eclipse nor with javac, but I think that both are wrong.
>>
>> public class ReferenceProblem {
>>   static class A {
>>     public A(Runnable r) { }
>>   }
>>
>>   static final A constant = new A(() -> {
>>     System.out.println(constant);
>>   });
>> }
>>
>> javac talks about 'self reference' but there is no self reference here, a lambda is a delayed computation.
>> 15.27.2 only concern local variables, so I don't think this code should be rejected.
>>
>> cheers,
>> Rémi
>>



More information about the lambda-spec-experts mailing list