Forward reference from lambda expression in field initializer

Markus Keller markus_keller at
Wed Dec 18 10:07:19 PST 2013

Dan Smith <daniel.smith at> wrote on 2013-12-17 23:27:01:
> 3 Dec 2013, Markus Keller <markus_keller at>, "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.

Sorry, the subject of my mail was misleading. I agree with not adding a 
way to refer to a lambda's "this".

> (In 8, local variables initialized with lambdas have a similar inability 
to directly refer to themselves.)

That restriction for local variables is not new in 8 and isn't exclusive 
to lambdas:

    static void post(Runnable r) { }
    void foo() {
        Runnable r1 = r1; // error: r1 not initialized
        Runnable r2 = () -> post(r2); // error: r2 not initialized
        Runnable r3 = new Runnable() {
            public void run() {
                post(r3); // error: r3 not initialized

The problem is actually not only about self-references from the lambda 
body of a field initializer, but about any forward reference that is 
forbidden by JLS7

A better example:
public class D {
    int v1 = value; // Error for (good).
    int v2 = D.this.value; // No simple name -> no error (good).
    IntSupplier s1 = () -> value; // Why error?
    IntSupplier s2 = new IntSupplier() {
        public int getAsInt() {
            return value; // No error (good).
    int value = 42;

There's absolutely no problem with the reference in s1's initializer. The 
only problem is that needs to be updated to make lambda bodies 
behave the same as nested class bodies.

======== should get a fifth point:
"- The usage is not in a lambda expression body that occurs inside c."

The next sentence could also be clarified to:
"It is a compile-time error if any of the five requirements above are not 
met for such a forward reference.

FWIW, this still excludes the forward reference to "VALUE" here:

    public static final IntConsumer c = (@A(VALUE) int x) -> {};
    public static final int VALUE = 42;


More information about the lambda-spec-observers mailing list