在JButton内部执行的最终变量是否需要? [英] inside JButton's actionperformed final variables required?

查看:95
本文介绍了在JButton内部执行的最终变量是否需要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个 JList ,我试图在 JButton s <$ c $中使用它c> actionPerformed 方法,它要求我制作 JList final 为什么,下面是一段代码片段

So i have a JList and i am trying to use it inside of a JButtons actionPerformed method and it is asking me to make the JList final why is that, below is a code snippet

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

我实际上没有问题让它最终成功,我只是不是确定为什么我需要。

I don't actually have a problem making it final, I just am not sure why i would need to.

推荐答案

要回答你的问题,你需要了解基础知识,了解JVM如何使用上班。
当编译包含内部类的类时,生成的字节代码实际上并不将内部类实现为类中的类。

To answer your question, you need to understand the basics, as to how the JVM use to work. When the classes are compiled which contain inner classes, the byte code which gets generated does not actually implement inner classes as a class within a class.

为什么错误:本地变量是从内部类访问的,需要声明它是最终的

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

编译此程序时,将有两个文件created,Foo.class和Foo $ 1.class。所以现在你的问题来了,因为第二个类,即 foo $ 1.class 不知道变量 edit 出现在 First 类中,即 foo.class

When you compile your this program, two files will be created, Foo.class and Foo$1.class. So now your problem comes, since the Second class i.e. foo$1.class doesn't know that Variable edit is present inside the First class i.e. foo.class.

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

So how to solve this problem ? What JVM does, is that, It makes a requirement for the developer to make the variable of an outer class to be declared as final.

现在这样做了,现在JVM在第二个编译的类文件中悄悄地放置一个名为val $ edit的隐藏变量,这里是从<$ c得到的输出$ c> javap

Now this being done, now JVM quietly places a hidden variable with the name val$edit inside the 2nd compiled class file, here is the output as got from javap

foo.class的输出

Ouput for foo.class

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

现在,编辑是构造函数的本地,因此输出如上所述。

Now since, edit is local to the constructor, hence the output as above.

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

变量 val $ edit被分配了相同的值,该值已被分配给编辑,因为现在编译器知道该值无法更改,因为它已被声明为final,因此它可以正常工作。

The Variable val$edit is assigned the same value which has been assigned to edit since now the compiler knows that the value cannot be changed as it has been declared final and hence it works this time.

现在如果我将 edit 变量 Local 更改为实例。现在,类的对象知道有关此变量 edit 的所有内容,如果它发生了变化。所以改变上面的程序同样我们得到:

Now what if I change the edit Variable from being Local to being Instance. Now the object of the class knows everything about this variable edit, if it gets changed. So changing the above program likewise we get :

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

在这种情况下,我们不打算申报并将其定义为 final ,因为在这种情况下,由于变量是整个类的本地,变量对象参考一起发送到内部类,即

Here in this case, we are not suppose to declare and define it as being final, because in this case since the Variable being Local to the whole class, the Variable is send to the Inner Class along with the Object Reference i.e. 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();
}

以下是变量在这种情况下发送,即此$ 0:

Here is how the Variable is send in this case i.e. 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);
}

根据我的说法,似乎是解释,这种情况如何运作。
刚才我在互联网上找到了关于的精彩解释本地内部类别中的可访问性之谜,可能会帮助您以更好的方式了解情况: - )

Seems like that the interpretation, how this situation works, according to me. Just now I found this wonderful explanation on the internet regarding Mystery of Accessibility in Local Inner Classes, might be this will help you understand the situation in a much better way :-)

这篇关于在JButton内部执行的最终变量是否需要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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