简体   繁体   English

Java:为什么我不能在任何类中使用final来访问局部变量JPanel?

[英]Java: Why could I access a local variable JPanel without final inside the anymous class?

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 ? 让我感到困惑的是,为什么我可以不使用final来访问JPanel

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. 它将允许使用panel变量引用的实例的状态进行突变。

The statement 该声明

a = 0; 

which attempts to assign a new value to a local variable in not allowed. 不允许尝试为本地变量分配新值。

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: 从一个lambda(或者匿名类)访问的任何引用(或变量)应该 最终的有效的决赛 ,这取决于你正在处理的Java版本:

  • prior to Java 8 the final keyword is a must; Java 8 之前 ,final关键字是必须的;
  • starting from Java 8 and going further it's enough to have it initialized once, the reference is treated as a effectively final; Java 8 开始,再进行一次初始化就足够了,该引用被视为有效的final;

Both concept stand for you cannot re-assign values from a lambda. 这两个概念都代表您不能从lambda重新分配值。

Here are related threads on this issue: 以下是与此问题相关的主题:

panel is not a local variable but a field. panel不是局部变量,而是字段。

Local variables are required to be effectively final (= not assigned after initialisation). 要求局部变量有效地是最终变量(=初始化后未分配)。

The reason is that a local variable is stored on the function call's stack. 原因是局部变量存储在函数调用的堆栈中。 Hence a lambda will copy the variable under the same name, so the function may end. 因此,lambda将以相同的名称复制变量,因此函数可能会结束。 Would either of those two variables be assignable, a schizophrene situation would arise. 如果这两个变量中的任何一个都是可分配的,则会出现精神分裂症。 Hence the rule. 因此,规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM