Bug in javac and eclipse ??

Zhong Yu zhong.j.yu at gmail.com
Tue Jan 21 19:36:19 PST 2014


On Tue, Jan 21, 2014 at 5:14 PM, Dan Smith <daniel.smith at oracle.com> 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?)

Prior to lambda, if a field initializer references the field itself,
it's highly likely that it is a programming mistake, for example, `int
y = y+1;`. It makes sense to forbid it because in all likelihood
that'll help the programmer.

But it is not true if the field is referenced inside a lambda body. It
is very un-likely that it is a programming mistake. It's most likely
what the programmer intends it to be.

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

I've encountered it in my real-world code. Basically the lambda is
registered as an one-off listener to some event; when the event
occurs, the lambda may need to register itself again. This example is
by no means contrived, and I'll bet $20 that we'll hear a lot of
complains why this cannot be done. And the workaround (prefixing with
"this." or "TheClass.") will only seem to be mysterious.

Zhong Yu

> An argument for more convenient recursive access in field initializers is probably also an argument for support for recursive access from local variable initializers.
>
> - In any case, you can always use qualified access ('System.out.println(ReferenceProblem.constant)'), for which 8.3.3 does not apply.
>
> —Dan
>
> 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-observers mailing list