Java actionPerformed方法中存在NullPointerException,但不在main中?

Java actionPerformed方法中存在NullPointerException,但不在main中?,java,Java,我理解NullPointerException是什么,但我的代码不理解当我移动 public class DictionaryClient implements ActionListener { JFrame frame = new JFrame("Amazing CW"); JPanel panel = new JPanel(); JButton button = new JButton("Send"); JTextField tex

我理解NullPointerException是什么,但我的代码不理解当我移动

    public class DictionaryClient implements ActionListener {

      JFrame frame = new JFrame("Amazing CW");
      JPanel panel = new JPanel();
      JButton button = new JButton("Send");
      JTextField  text = new JTextField("Field");
      Book book;
      DictionaryService port;

    public DictionaryClient() {

    panel.add(button);
    panel.add(text);
    frame.add(panel);
    button.addActionListener(this);
    frame.setSize(300,300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    }

    public static void main(String[] args){

    DictionaryClient client = new DictionaryClient();
    DictionaryServiceService service = new DictionaryServiceService();
    DictionaryService port = service.getDictionaryServicePort();

    Book book = port.sendBook();

}

    @Override
     public void actionPerformed(ActionEvent e) {
               if(e.getSource() == button){
                  System.out.print(book.getAuthor() + " " + book.getTitle());
               }
        }
}
从执行的操作中,我一点问题也没有

System.out.print(book.getAuthor() + " " + book.getTitle());
创建名为
book
的局部变量。它不会影响
DictionaryClient
类中的
book
字段,该字段保持其默认值
null
。将其更改为:

Book book = port.sendBook();
这将把值分配给
DictionaryClient
对象上的正确字段

现在,只要主方法结束,局部变量超出范围,该值就会丢失。当您将
print
移动到main方法中时,它能够引用局部变量,但在
actionPerformed
方法中,范围内唯一的
book
是字段,该字段从未初始化

创建名为
book
的局部变量。它不会影响
DictionaryClient
类中的
book
字段,该字段保持其默认值
null
。将其更改为:

Book book = port.sendBook();
这将把值分配给
DictionaryClient
对象上的正确字段


现在,只要主方法结束,局部变量超出范围,该值就会丢失。当您将
print
移动到主方法中时,它能够引用局部变量,但在
actionPerformed
方法中,作用域中唯一的
book
是字段,该字段从未初始化。

您的book对象在主方法中只有局部作用域。您需要将其范围更改为类的本地范围(您已经引用了该类)

只要换一行就行了

client.book = port.sendBook();


这将正确设置类级别book变量。然后,actionPerformed方法将相应地引用该实例变量。

您的Book对象在main方法中只有局部作用域。您需要将其范围更改为类的本地范围(您已经引用了该类)

只要换一行就行了

client.book = port.sendBook();

这将正确设置类级别book变量。然后,actionPerformed方法将相应地引用该实例变量。

请检查以下内容: 以下声明/初始化

client.book = port.sendBook();
是在静态主方法内部创建的,由于类DictionaryClient有一个同名的成员,因此主方法中的此对象是隐藏DictionaryClient的书,当触发
actionPerformed
时,您不再处于静态主方法中,所以你的定义好了,初始化好了,就永远回来了。。。 该范围内唯一可用的书籍是类中定义的

但从未初始化,因此是NPE。

请查看以下内容: 以下声明/初始化

client.book = port.sendBook();
是在静态主方法内部创建的,由于类DictionaryClient有一个同名的成员,因此主方法中的此对象是隐藏DictionaryClient的书,当触发
actionPerformed
时,您不再处于静态主方法中,所以你的定义好了,初始化好了,就永远回来了。。。 该范围内唯一可用的书籍是类中定义的


但is从未初始化,因此是NPE。

Perfect:)谢谢!完美:)谢谢你!由于
main
是静态的,因此他们还需要使用对
DictionaryClient
的引用来访问
book
。是的,非常正确。谢谢你的答案是更好的:)因为
main
是静态的,他们还需要使用对
DictionaryClient
的引用来访问
book
。是的,非常正确。谢谢你的答案更好:)