JDK-8042405 : Can't compile Lambda referencing final variable initialized on constructor
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2014-05-05
  • Updated: 2014-05-14
  • Resolved: 2014-05-14
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When a Lambda expression defined as a class instance references a final variable that is initialized only inside a constructor, but without calling "this." before the variable, the compiler throws a compilation error.

With the "this." before the variable, the compiler works fine.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See provided source code to compile.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Compiling 2 source files to /home/bruno/javabug/build/classes
/home/bruno/javabug/src/FooBar.java:14: error: variable foobar might not have been initialized
        System.out.println(foobar); // throws compilation error
1 error

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/**
 * @author bruno.borges@oracle.com
 */
public class FooBar {

    private final String foobar;

    public FooBar() {
        foobar = "foobar";
    }

    private final java.util.function.Function ds = n -> {
        System.out.println(this.foobar); // compiles successfuly
        System.out.println(foobar); // throws compilation error: "variable foobar might not have been initialized"

        return foobar;
    };

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The reference to the variable must be preceded with "this." or else the compiler throws a compilation error.


Comments
I note that the DA/DU rules are not spelled out as well as they should be for lambda expressions. See JDK-8043176.
14-05-2014

The discrepancy between 'this.foobar' and 'foobar' is covered by JDK-8039026 -- they should be treated the same. Otherwise, the error is as specified: the field is not Definitely Assigned before its reference, so an error occurs. (Unlike anonymous classes, lambda expressions do not treat all blank final fields as automatically DA within their bodies.)
14-05-2014