Lambda expression using a final field in object initialization block

Jaikiran Pai jai.forums2013 at gmail.com
Mon Mar 4 09:56:28 UTC 2019


Please consider this trivial code:


import java.util.Map;
import java.util.HashMap;
import java.util.function.Supplier;

public class LambdaTest {
    private final String name;

    private final Map<String, Supplier<String>> suppliers = new HashMap<>();

    {
        this.suppliers.put("a", () -> name);
    }

    private LambdaTest(final String name) {
        this.name = name;
    }

    public static void main(final String[] args) throws Exception {
        final LambdaTest self = new LambdaTest("hello");
    }
}

When I compile this with Java 8 (javac 1.8.0_172) and even Java 11
(javac 11.0.1), I get a compilation error, in the object initialization
block where I am using a lambda expression to populate the "suppliers"
Map and am referring to a final field (called "name") of the class. The
compilation error is:

LambdaTest.java:12: error: variable name might not have been initialized
        this.suppliers.put("a", () -> name);
                                      ^
1 error

Now, if I replace that piece of code with:


import java.util.Map;
import java.util.HashMap;
import java.util.function.Supplier;

public class LambdaTest {
    private final String name;

    private final Map<String, Supplier<String>> suppliers = new HashMap<>();

    {
        this.suppliers.put("a", new Supplier<String>() {
            @Override
            public String get() {
                return name;
            }
        });
    }

    private LambdaTest(final String name) {
        this.name = name;
    }

    public static void main(final String[] args) throws Exception {
        final LambdaTest self = new LambdaTest("hello");
    }
}

The only change in this is the object initialization block, where I no
longer use a lambda and instead use an anonymous class. This passes
compilation successfully.

Why is it an error to use such a final field in a lambda expression? The
(basic) documentation[1] of Lambda expressions doesn't seem to mention
this construct as invalid.


[1]
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

-Jaikiran




More information about the jdk-dev mailing list