Java JButton.actionPerformed:空指针异常

Java JButton.actionPerformed:空指针异常,java,swing,jbutton,Java,Swing,Jbutton,我正在阅读一本书,下面的代码在运行时单击JButton时在line button.actionPerformed处抛出一个NPE。我已经尽了最大努力确保我的代码与书中的代码完全一致,有人能指出我的问题吗?(这本书是为java 5编写的,我使用的是最新的java 7,但据我所知,这不会对以下代码产生任何影响) 在一个方法中,您有: JButton button = new JButton("click here"); 这将创建变量,但此新变量的范围在方法内部。不过,您已经在类中声明了按钮。应该是

我正在阅读一本书,下面的代码在运行时单击JButton时在line button.actionPerformed处抛出一个NPE。我已经尽了最大努力确保我的代码与书中的代码完全一致,有人能指出我的问题吗?(这本书是为java 5编写的,我使用的是最新的java 7,但据我所知,这不会对以下代码产生任何影响)


在一个方法中,您有:

JButton button = new JButton("click here");
这将创建变量,但此新变量的范围在方法内部。不过,您已经在类中声明了
按钮。应该是:

button = new JButton("click here");

在一个方法中,您有:

JButton button = new JButton("click here");
这将创建变量,但此新变量的范围在方法内部。不过,您已经在类中声明了
按钮。应该是:

button = new JButton("click here");

原因是这一行:

JButton button = new JButton("click here");
这里您正在创建新的本地
JButton
对象,它是成员变量
按钮
。因此,
按钮
仍然是
空的
。您应改为使用:

button = new JButton("click here");

原因是这一行:

JButton button = new JButton("click here");
这里您正在创建新的本地
JButton
对象,它是成员变量
按钮
。因此,
按钮
仍然是
空的
。您应改为使用:

button = new JButton("click here");

你在隐藏你的变量

按钮
声明为类变量,但在
go
方法中重新声明,这意味着类变量(在
actionPerformed
方法中引用)为空


更改
JButton按钮=新建JButton(“单击此处”)
to
button=newjbutton(“单击此处”)

您正在隐藏变量

按钮
声明为类变量,但在
go
方法中重新声明,这意味着类变量(在
actionPerformed
方法中引用)为空


更改
JButton按钮=新建JButton(“单击此处”)
to
button=newjbutton(“单击此处”)

嗯,你的
按钮仍然是
null
。在程序中的任何地方都没有分配它

好吧,您的
JButton按钮
仍然为
null
。在程序中的任何位置都没有分配它

此问题称为“变量隐藏”或“隐藏变量”或“隐藏变量”。也就是说,一个局部变量隐藏了另一个同名的变量。您已经在
go
方法中重新定义了变量
按钮
。刚从go方法中删除了重新定义,所以它可以正常工作。请看下面的代码

import javax.swing.*;
import java.awt.event.*;

public class SimpleGui implements ActionListener {
JButton button;
public static void main(String[] args) {
    SimpleGui gui = new SimpleGui();
    gui.go();
}

public void go() {
    JFrame frame = new JFrame();
     button = new JButton("click here"); //Variable Re definition removed

    button.addActionListener(this);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.getContentPane().add(button);
    frame.setSize(300,300);
    frame.setVisible(true);
}

public void actionPerformed(ActionEvent event) {
    button.setText("I've been clicked, argh!");
}

}
由于您似乎对JavaGUI还不熟悉,请接受以下几点建议

  • 在构造函数中定义类变量始终是最佳实践
  • 使用访问说明符
    private
    按钮
    变量的良好说明符
  • 尽管可以自动创建构造函数(默认构造函数),但最好是自己编写,至少是空的
  • 这个问题被称为“变量隐藏”或“隐藏变量”或“隐藏变量”。也就是说,一个局部变量隐藏了另一个同名的变量。您已经在
    go
    方法中重新定义了变量
    按钮
    。刚从go方法中删除了重新定义,所以它可以正常工作。请看下面的代码

    import javax.swing.*;
    import java.awt.event.*;
    
    public class SimpleGui implements ActionListener {
    JButton button;
    public static void main(String[] args) {
        SimpleGui gui = new SimpleGui();
        gui.go();
    }
    
    public void go() {
        JFrame frame = new JFrame();
         button = new JButton("click here"); //Variable Re definition removed
    
        button.addActionListener(this);
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        frame.getContentPane().add(button);
        frame.setSize(300,300);
        frame.setVisible(true);
    }
    
    public void actionPerformed(ActionEvent event) {
        button.setText("I've been clicked, argh!");
    }
    
    }
    
    由于您似乎对JavaGUI还不熟悉,请接受以下几点建议

  • 在构造函数中定义类变量始终是最佳实践
  • 使用访问说明符
    private
    按钮
    变量的良好说明符
  • 尽管可以自动创建构造函数(默认构造函数),但最好是自己编写,至少是空的

  • 那么堆栈跟踪是什么呢?那么堆栈跟踪是什么呢?所以要修复它…如果我将其更改为read
    button=new JButton(“单击此处”)那么它不是创建一个新对象JButton,只是一个新对象与JButton按钮关联,而JButton按钮当时已经存在?因此,当调用button.setText时,它有地方可去。这是正确的想法吗?@nexus_2006是的,当您更改到此代码时,将创建一个新的
    JButton
    对象,并且该对象将被class
    SimpleGui
    的成员变量引用。因此,当您在
    actionPerformed
    中调用
    button.setText
    时,它将通过
    button
    变量看到新创建的对象,因此没有NPESo来修复它…如果我将其更改为read
    button=new JButton(“单击此处”)那么它不是创建一个新对象JButton,只是一个新对象与JButton按钮关联,而JButton按钮当时已经存在?因此,当调用button.setText时,它有地方可去。这是正确的想法吗?@nexus_2006是的,当您更改到此代码时,将创建一个新的
    JButton
    对象,并且该对象将被class
    SimpleGui
    的成员变量引用。因此,当您在
    actionPerformed
    中调用
    button.setText
    时,它将通过
    button
    变量看到新创建的对象,因此我想说没有NPEA小的修改。
    您将button声明为实例变量(不是类变量)
    ;)作为一个小修改,我想说..
    您将按钮声明为实例变量(不是类变量)
    ;)