当前位置: 首页 > 面试题库 >

无法分配最终的局部变量

锺离赤岩
2023-03-14
问题内容

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

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

    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);

问题答案:

关键是封闭类型中的方法局部变量实际上已 复制
到匿名类的实例中(这是由于激活框架的问题,但我将不做进一步的详细介绍,因为这与问题无关)。这就是为什么它们需要是final的原因,因为嵌套类型实例中的变量不再相同。

因此,这是第一个示例:

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

这不会编译,因为您无法在匿名类的方法中引用非最终变量。当您在的声明中添加最终修饰符时a,的值a将被复制到您定义的匿名类的创建实例中。但是,将不允许您更改的值a,因为所做的更改对于a声明位置的方法不可见。

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

int a = 3;

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

该示例确实进行了编译,a每次run()调用匿名类实例的方法时,它都会增加3 。(在此示例中,从不调用它,而只是一个示例。)

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

更新: 在Java 8中,引入了 有效的最终
变量的概念(请参阅Java语言规范)。但是,在此帖子的第一个示例中,变量a被多次分配,这使变量无法有效地最终确定。这意味着该示例仍无法使用Java
8进行编译。(编译错误为“在封闭范围内定义的局部变量a必须是最终的或实际上是最终的”)



 类似资料:
  • 问题内容: 我想知道使用最终局部变量是否有可用性。当继承出现时,变量无论如何都不会被覆盖。例如下面的简单代码 这个例子很简单,可能不是一个相关的代码,但是问题比较笼统。我已经看到了很多代码(全部都包含在具有最终局部变量的main函数中)是否有将局部变量声明为final other的可用性。不能在同一功能中进行编辑? 问题答案: 首先,关于变量被“覆盖”的部分具有两个非常不同的含义。对于类和方法,它

  • 问题内容: 我想知道你们是否可以提供帮助。我试图做一个简单的视图,它将用户发送到客户端创建表单,但是我一直收到此错误: 赋值之前引用的局部变量“ form” 查看我的代码,看不到有什么问题。 有人告诉我我哪里出问题了吗? 问题答案: 这是正在发生的事情: 没有输入该块。 变量未定义。 然后,你尝试在语句中引用变量。 至于解决方法,这确实是你要决定的。解决的方法取决于你希望代码执行的操作(如果请求方

  • 这个程序是我的类的最终赋值,我在弄清楚为什么我收到错误“从内部类引用的局部变量必须是最终的或实际上是最终的”时遇到了问题。该程序正在运行并发线程来对#的数组进行排序,然后找到该数组的高值和低值。当我在没有并发的情况下创建它时,我没有这个错误。我正在努力确定在哪里最终确定高变量和低变量。 这是产生错误的代码块。如果我使int高=数字[0];或int-low=数字[0];final,然后我得到一个错误

  • 问题内容: 请看以下示例: 首先,存放在哪里?是吗: 由编译器复制到引用它的内部类的隐藏成员变量中 复制到堆并在堆上引用 留在堆栈上并以某种方式引用 其他的东西 我的 猜测 是第一选择。 其次,要做到这样做所引起的任何性能问题(而不是简单地作为类的成员变量创建并按其引用),尤其是当您创建大量引用最终局部变量的内部类构造时。 问题答案: 是的,它们已被复制,这就是为什么您必须将变量声明为final的

  • 问题内容: 作为Eclipse的长期用户,我正在与IntelliJ IDEA 10一起玩耍。我似乎找不到如何执行“向新局部变量分配语句”代码完成的工作。 功能说明: 我输入类似 然后按+ 并输入,Eclipse将行更改为: 同时,我可以立即键入“ bufferedOutputStream”以将其重命名(或从下拉菜单中选择“ bufferedOutputStream”,“ outputStream”

  • 问题内容: 在lambda中,局部变量需要是最终变量,而实例变量则不需要。为什么这样? 问题答案: 字段和局部变量之间的根本区别在于,当JVM创建lambda实例时,将复制局部变量。另一方面,字段可以自由更改,因为对它们的更改也将传播到外部类实例(它们的范围是整个外部类,如Boris所指出的)。 考虑到匿名类,闭包和Labmdas的最简单方法是从可变范围的角度来看。想象一个为传递给闭包的所有局部变