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

在JButton的action内部执行所需的最终变量?

翟永春
2023-03-14
问题内容

所以我有一个,JList并且我正在尝试在JButtons actionPerformed方法中使用它,并且正在问我JList
final为什么这样做,下面是一个代码片段

public SomeClass() {    
  btnNewButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         list.clearSelection();             
    }});
}

实际上,将其定型没有问题,只是我不确定为什么需要这样做。


问题答案:

要回答您的问题,您需要了解有关JVM如何工作的基础知识。当编译包含内部类的类时,生成的字节码实际上并未将内部类实现为类中的类。

错误原因:局部变量是从内部类访问的,需要将其声明为final

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenu;
import javax.swing.JPanel;

public class foo extends JPanel
{  
  public foo()
  {
    final JMenu edit = new JMenu();
    edit.getItem(0).addMouseListener(new MouseAdapter(){ 
    @Override
        public void mouseClicked(MouseEvent e) 
        {
            if (e.getClickCount() == 1) {
                edit.getItem(0).setEnabled(true);
            }
        } 
    });
  }
}

编译此程序时,将创建两个文件Foo.class和Foo $ 1.class。现在,您的问题来了,因为Second类ie
foo$1.class不知道类ie 中Variable edit是否存在First该类foo.class

那么如何解决这个问题呢?是什么JVM呢,就是, 它使开发人员,使外部类的变量被声明为final的要求

现在完成了,现在JVM在第二个编译的类文件中安静地放置了一个名为val $ edit的隐藏变量,这是从 javap

foo.class的输出

C:\Mine\JAVA\J2SE\folder>javap foo.class
Compiled from "foo.java"
public class foo extends javax.swing.JPanel {
  public foo();
}

现在,edit对于构造函数是本地的,因此输出如上。

C:\Mine\JAVA\J2SE\folder>javap foo$1.class
Compiled from "foo.java"
class foo$1 extends java.awt.event.MouseAdapter {
  final javax.swing.JMenu val$edit;
  final foo this$0;
  foo$1(foo, javax.swing.JMenu);
  public void mouseClicked(java.awt.event.MouseEvent);
}

Variable因为现在编译器知道,因为它已经被声明为final的价值不能被改变,因此它的工作原理这次VAL $编辑分配已分配给编辑的值相同。

现在,如果我改变edit
Variable的是Local对是Instance。现在edit,如果更改了该变量,该类的对象就知道所有有关此变量的信息。因此,同样更改上面的程序,我们得到:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenu;
import javax.swing.JPanel;

public class foo extends JPanel
{  
    JMenu edit = new JMenu();

    public foo()
    {   
        edit.getItem(0).addMouseListener(new MouseAdapter(){ 
        @Override
            public void mouseClicked(MouseEvent e) 
            {
            if (e.getClickCount() == 1) {
                    edit.getItem(0).setEnabled(true);
                }
            } 
        });
    }
}

在这种情况下,我们不假定将其声明和定义为as
final,因为在这种情况下,由于在Variable整个类中都是Local,所以Variable将连同Object Referenceie
一起发送到内部类this

C:\Mine\JAVA\J2SE\folder>javap foo.class
Compiled from "foo.java"
public class foo extends javax.swing.JPanel {
  javax.swing.JMenu edit;
  public foo();
}

这是Variable在这种情况下,即this $ 0发送的方式:

C:\Mine\JAVA\J2SE\folder>javap foo$1.class
Compiled from "foo.java"
class foo$1 extends java.awt.event.MouseAdapter {
  final foo this$0;
  foo$1(foo);
  public void mouseClicked(java.awt.event.MouseEvent);
}

根据我的说法,这种情况似乎是一种解释。刚才我在互联网上发现了有关本地内部类无障碍获取之谜的精彩解释,也许这将有助于您更好地了解情况:-)



 类似资料:
  • 问题内容: 尝试在内部类内部使用一个类的本地成员时遇到此错误。我知道将其声明为final将解决此问题,但我读到Java 8应该自动处理它,因为我将Intellij与Java 8一起使用,但它仍然无法编译。还有其他方法可以在不将其声明为final的情况下进行修复吗?谢谢。 问题答案: 我知道将其声明为final将解决此问题,但我读到Java 8应该自动处理它。 如果变量 有效地为final ,则Ja

  • 我正在尝试让一个按钮将其值与其他变量进行比较。在onClick方法中,我收到一个错误,说变量在内部类中被访问,需要声明为最终变量。问题是变量应该被更改,所以我无法使其成为最终变量。我如何解决这个问题?这是我的代码:

  • 我在中发现了一个编译错误。 代码是这样的。

  • 问题内容: 因此标题说明了一切。我的内出现编译错误。 这是代码。 问题答案: 如果您不想使其最终确定,则始终可以将其设为全局变量。

  • 问题内容: 如果省略,则会看到错误“ 无法在用其他方法定义的内部类中引用非最终变量jtfContent ”。 为什么匿名内部类必须要求外部类实例变量为final才能访问它? 问题答案: 首先,让我们放松一下,请放下那把枪。 好。现在,语言坚持的原因是它作弊是为了让你的内部类函数可以访问他们渴望的局部变量。运行时复制本地执行上下文(以及其他适当的内容),因此它坚持要求你进行所有操作,final以使事

  • 我的代码有上述错误。我尝试通过将我的btnsav声明为最终版本来修复此问题,但随后我收到另外两个错误: 未知类:“btnsave” 不是一个声明 你知道我如何修复这个错误吗?