JDK-8077667 : 'variable may not have been initialized' error for parameter in lambda function
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u40,9
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2015-04-10
  • Updated: 2018-11-22
  • Resolved: 2015-05-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b68Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux dev 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
When a return statement exists in a constructor, and a parameterized lambda is defined at the class level, javac throws an error stating 'variable ___ might not have been initialized' for the parameter passed into the lambda. The error is thrown at the return statement, where the parameter in question is out of scope.

For example, running javac against this code snippet:

public class Main {

    Predicate<String> predicate = var -> var.isEmpty();

    Main() {
        return;
    }
}

produces the error:
Error:(8, 9) java: variable var might not have been initialized

Replacing the lambda expression with an anonymous declaration (as below) eliminates the compiler error:

Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.isEmpty();
            }
        };

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try compiling the provided executable test case.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class JavacBugMain {

    public static void main(String[] args) {
        new Inner();
    }

    private static class Inner {
        Predicate<String> synonymComparator = a -> a.isEmpty();

        Inner() {
            if (true) {
                return;
            }

            synonymComparator.test("");
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Convert the lambda expression to an anonymous class.


Comments
Maurizio, this looks like a candidate for backport - do you agree ?
30-05-2015

Reproduced, I'll follow up.
28-05-2015

I confirm this with 1.9.0-ea-b63. I'll defer to the devs for evaluation.
11-05-2015

1) Run the attached test case (JavacBugMain.java) 2) Tested this on Linux and Windows 7 (64-bit) with JDK 8u31, 8u40, 8u60 ea b07 and 9 ea b57. ****************************************************************************************** 8u31: FAIL 8u40: FAIL 8u60 ea b07: FAIL 9 ea b57: FAIL ******************************************************************************************* Output (JDK 8u40): >javac JavacBugMain.java JavacBugMain.java:14: error: variable a might not have been initialized return; ^ 1 error ************************************************************************************************** Result: The error is reproducible with JDK 8u40, 8u60 ea b06 and 9 ea b57.
14-04-2015