无法分配最终的局部变量 [英] The final local variable cannot be assigned

查看:119
本文介绍了无法分配最终的局部变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个座位数组,数组有两个字符串(选中和空)。在鼠标单击时,我想遍历数组并找到所选的座位。当我按下按钮时,它说:

I have an array of seats, and the array has two strings(selected and empty). On mouse click, I want to traverse the array and find the selected seat. When I press the button it says:


无法分配最终的局部变量seatno,因为它是在封闭类型中定义的。

The final local variable seatno cannot be assigned, since it is defined in an enclosing type.



    JButton btnContinue = new JButton("Next");
    btnContinue.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent arg0) {

            for(int x=0;x<17;x++){
                if(anArray[x]=="selected"){

                    seatno = anArray[x];
                }
            }

            data page=new data(newfrom,newto,newtime,date2,seatno);
            page.setVisible(true);
            setVisible(false);
        }
    });
    btnContinue.setBounds(358, 227, 62, 23);
    contentPane.add(btnContinue);


推荐答案

重点是来自封闭的方法局部变量类型实际上是复制到匿名类的实例(这是因为激活框架问题,但我不会进一步详细说明,因为这与问题无关),这就是他们需要的原因最后,因为嵌套类型实例中的变量不再相同。

The point is that method-local variables from the enclosing type are actually copied to instances of anonymous classes (this is because of activation frame issues, but I won't go further into detail as this is not really relevant to the question), which is why they need to be final, because the variable in the nested type instance is not the same anymore.

所以,这是第一个例子:

So, here is the first example:

void foo() {
    int a = 3;
    new Runnable() {
        @Override
        public void run() {
            a += 3;
        }
    };
}

这不能编译,因为你不能在一个非最终变量中引用匿名类的方法。将最终修饰符添加到 a 的声明中时, a 的值将被复制到创建的实例中您定义的匿名类。但是,您将无法更改 a 的值,因为 a 已声明。

This does not compile, because you cannot reference a non-final variable in an anonymous class' method. When you add a final modifier to the declaration of a, the value of a would be copied into the created instance of the anonymous class you have defined. However, you will not be allowed to change the value of a, because the changes would not be visible to the method where a was declared.

但是,匿名类不是静态的,也就是说,它们具有对封闭实例的引用(除非它们声明的方法是静态的)您可以使用它来修改封闭实例的变量:

However, anonymous classes are not static, that is, they have a reference to the enclosing instance (unless the method where they are declared is static) which you can use to modify variables of the enclosing instance:

int a = 3;

void foo() {
    new Runnable() {
        @Override
        public void run() {
            a += 3;
        }
    };
}

此示例进行编译,它会增加 a 每次调用匿名类'实例的 run()方法时为3。 (在这个例子中它永远不会被调用,但它只是一个例子。)

This example does compile and it would increase a by 3 every time the run() method of the anonymous class' instance is called. (In this example it is never called, but it is just an example.)

因此,总而言之,你需要转换变量 seatno 从方法局部变量到封闭类型的实例变量。或者,如果还没有,则需要删除最终修饰符,因为最终变量只能分配一次。

So, to summarize, you need to convert the variable seatno from a method-local variable to an instance variable of the enclosing type. Or, if it is yet, you need to remove the final modifier as final variables can only be assigned once.

更新:在Java 8中,引入了有效最终变量的概念(参见 Java语言规范)。但是,在这篇文章的第一个例子中,变量 a 被多次分配,这阻止了它实际上是最终的。这意味着此示例仍然无法使用Java 8进行编译。(编译错误是在封闭范围中定义的局部变量必须是最终的或有效的最终)

Update: In Java 8, the concept of effectively final variables is introduced (see Java Language Specification). However, in the first example of this post, the variable a is assigned multiple times, which prevents it from being effectively final. This means that this example still does not compile with Java 8. (The compile error is "Local variable a defined in an enclosing scope must be final or effectively final")

这篇关于无法分配最终的局部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆