Reference a blank final field from lambda body

Zhong Yu zhong.j.yu at gmail.com
Fri Dec 20 14:31:12 PST 2013


The following code does not compile (jdk8b120), where a blank final
field is referenced from a lambda body by its simple name

public class Tmp
{
    final int i;

    public Tmp(int i)
    {
        this.i = i;
    }

    void r()
    {
        int k = i; // [1]
    }

    final Runnable r = ()->
    {
        int k = i; // [2]   javac error: `i` not initialized
    };
}

which is unfortunate, because this pattern of usage is quite innocent;
people are probably going to do it a lot. There's no apparently reason
why [1] is ok but [2] is not.

Anyways, the workaround seems to be to prefix the simple name with "this."

    final Runnable r = ()->
    {
        int k = this.i;
    };

It compiles in javac, *however*, I cannot take javac's word for it at
this point [1]. Someone please confirm that this workaround is correct
and is intended by the spec. Or if it is not, what other workarounds
are available.

Zhong Yu

[1] Why javac seems unreliable on this matter - it also compiles this code

public class Tmp
{
    final int i;

    public Tmp(int i)
    {
        this.i = this.i; // it compiles! bug or feature?
    }
}


More information about the lambda-dev mailing list