1

Suppose the code is:

public class Test {
    public void test() {
        JPanel panel = new JPanel();
        int a;
        JLabel label = new JLabel();
        label.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                panel.setBackground(Color.BLACK); // Correct
                a = 0; // Wrong, should be final
            }
        });
    }
}

It confuses me that why I can access the JPanel without a final?

Paul Zhang
  • 305
  • 2
  • 7

2 Answers2

2

Any references (or variables) accessed from a lambda (or an anonymous class) should be either final or effectively final, it depends on Java version you are dealing with:

  • prior to Java 8 the final keyword is a must;
  • starting from Java 8 and going further it's enough to have it initialized once, the reference is treated as a effectively final;

Both concept stand for you cannot re-assign values from a lambda.

Here are related threads on this issue:

1

The statement

panel.setBackground(Color.BLACK);

doesn't assign a value to a local variable (which is not allowed inside the anonymous class method). It mutates the state of the instance referenced by the panel variable, which is allowed.

The statement

a = 0; 

which attempts to assign a new value to a local variable in not allowed.

Eran
  • 387,369
  • 54
  • 702
  • 768