An unexpected error occurred while using Lambdas in Java 8

I use Java 8 update 20 32-bit, Maven 3.2 3. Eclipse Luna build ID: 20140612-0600 32 bits

After I started using Lambdas, some classes in my project started reporting MVN compile errors in Maven

These errors only occur when I use Lambdas If I switch back to the anonymous class, the error disappears

I can reproduce the error through a simple test case:

package br;

import java.awt.Button;
import java.awt.Panel;

public class Test {

    private final Button button;
    private final Panel panel;

    public test() {
        button = new Button();
        button.addActionListener(event -> {
            System.out.println(panel);
        });
        panel = new Panel();
    }
}

I compile this:

mvn clean;mvn compile

I received this error:

[ERROR] /C:/Users/fabiano/workspace-luna/Test/src/main/java/br/Test.java:[14,44] variable panel might not have been initialized

Although the error message is very clear about what is happening (the compiler thinks that the final variable panel will be called before instantiation), the variable will not be called before the button generates the action, and we can't say that the action will happen. The code should be compiled In fact, if I don't use lambda, it will compile as it should:

package br;

import java.awt.Button;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Test {

    private final Button button;
    private final Panel panel;

    public test() {
        button = new Button();
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(panel);
            }
        });
        panel = new Panel();
    }
}

I noticed two other strange things related to this problem:

>Eclipse does not report this error when automatically compiling classes Eclipse uses the same JDK as Maven to compile classes. > If I use Maven to compile a class using anonymous classes, I change the class to use Lambdas and compile it again using maven, which will not report errors In this case, if I use MVN clean and then MVN compile, it will only report the error again

Can someone help me solve this problem? Or try to reproduce the problem?

Solution

You should consider that the compiler follows formal rules and does not know your facts In particular, the compiler cannot know that the method addactionlistener will not call the actionperformed method immediately It also doesn't know the visibility of the button, and it determines when actionperformed can be called

Formal behavior has a specification There you will find the following:

Chapter 16. Definite Assignment

and

15.27. 2. Lambda Body

In your code, the meaning of lambda body name, panel reading, is the same as the context around the constructor In this context, the rule "each blank final field must have an explicit assignment when any access to its value occurs" applies

And, yes, this is different from the internal class definition The specification clearly points out this point

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>