Java内部类空指针异常

Java内部类空指针异常,java,multithreading,exception,pointers,null,Java,Multithreading,Exception,Pointers,Null,我正在使用的聊天客户端代码生成以下错误: "Exception in thread "Thread-0" java.lang.NullPointerException at ChatClient$FieldLengthChecker.run(ChatClient.java:26)" 此错误仅在大约50%的时间内发生。 另外50%的时间,程序按预期运行 该线程用于侦听userAuthField中的字符,以确保用户在设置authLoginButton.setEnabledtrue之前输入至少4个字

我正在使用的聊天客户端代码生成以下错误:

"Exception in thread "Thread-0" java.lang.NullPointerException at ChatClient$FieldLengthChecker.run(ChatClient.java:26)"
此错误仅在大约50%的时间内发生。 另外50%的时间,程序按预期运行

该线程用于侦听userAuthField中的字符,以确保用户在设置authLoginButton.setEnabledtrue之前输入至少4个字符

如果authUserField内容的长度低于4个字符,则应禁用该按钮

如果我运行该程序并在字段中输入4个字符,则它要么给我上面列出的异常,要么在我关闭应用程序之前运行良好,如中所示,我可以添加和删除字符,按钮将按预期激活/停用,直到我关闭该程序

非常感谢您的任何见解

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

public class ChatClient {
    JFrame authFrame;
    JPanel authPanel;
    JLabel authUserLabel;
    JLabel authPassLabel;
    JLabel authMessageLabel;
    JTextField authUserField;
    JTextField authPassField;
    JButton authLoginButton;
    JButton authRegisterButton;

    String authUserData;
    String authPassData;

    //This inner-class is used in a thread to listen
    //for characters entering and exiting the userAuthField
    //in order to change the status of authLoginButton
    public class FieldLengthChecker extends Thread {

        public void run() {
            while(true) {
               String username = authUserField.getText();
               if (username.length() > 3) {
                   authLoginButton.setEnabled(true);
                }
                else {
                     authLoginButton.setEnabled(
                }
            }
        }
    }

    public static void main(String[] args) {
        ChatClient chat = new ChatClient();
        chat.start();
    }

    public void start() {
        FieldLengthChecker FieldLengthChecker = new FieldLengthChecker();
        authFrame = new JFrame("Authentication");
        authFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        authPanel = new JPanel();
        authUserLabel = new JLabel("Username");
        authPassLabel = new JLabel("Password");
        authMessageLabel = new JLabel();
        authUserField = new JTextField(20);
        authPassField = new JTextField(20);
        authLoginButton = new JButton("Login");
        authLoginButton.addActionListener(new AuthLoginButtonListener());
        authLoginButton.setEnabled(false);
        authRegisterButton = new JButton("Register");
        authFrame.getContentPane().add(authPanel);
        authPanel.add(authUserLabel);
        authPanel.add(authUserField);
        authPanel.add(authPassLabel);
        authPanel.add(authPassField);
        authPanel.add(authLoginButton);
        authPanel.add(authMessageLabel);
        authFrame.setSize(250, 300);
        authFrame.setVisible(true);
        FieldLengthChecker.start();
    }

    //This inner-class takes the user and pass information from
    //authUserField and authPassField and sends it to the 
    //Authentication server to query the associated database
    class AuthLoginButtonListener implements ActionListener {
        Socket authSock;
        BufferedReader authReader;
        PrintWriter authWriter;
        public void actionPerformed(ActionEvent event) {
            try {
                authSock = new Socket("127.0.0.1", 5001);
                InputStreamReader streamReader = new InputStreamReader(authSock.getInputStream());
                authReader = new BufferedReader(streamReader);
                authWriter = new PrintWriter(authSock.getOutputStream());
                System.out.println("Connection established with Authentication server");

                authUserData = authUserField.getText();
                authPassData = authPassField.getText();

                authWriter.println(authUserData + " " + authPassData);
                authWriter.close();
            }
            catch(Exception ex) {
                ex.printStackTrace();
                System.out.println();                                                   
                System.out.println("Failed to establish a connection with the authentication server.");
                System.out.println("See above stack trace for further information.");
                authFrame.dispose();
            }
        }
    }
}

试试这样的

public class FieldLengthChecker extends Thread {

    public void run() {
        while(true) {
           try {
                String username = authUserField.getText();
                if (username.length() > 3) {
                    authLoginButton.setEnabled(true);
                } else {
                    authLoginButton.setEnabled(false);
                }
            } catch (NullPointerException e) {
                // handle exception
            }
        }
    }
}

你试过使用调试器吗?或者,您是否已将println零碎地添加到可能存在问题的位置?我之前添加过,但我将其删除,以使其对stackoverflow用户更为友好。我在其中放置了几个println条目作为“中断”,但也没有用。不过,我对了解一个好的Java调试器很感兴趣。作为一个业余爱好者,我认为我应该手动调试一切,以便更好地理解Java的工作原理。那么第26行在哪里呢?这是第26行:如果username.length>3{优秀的RaidZero。工作起来很有魅力。目前,将异常转储到虚无中似乎是可以接受的,因为我已经测试了大约40次,并且它按预期运行。谢谢!为什么不只是检查用户名是否为空,而不是捕获异常?我一开始没有意识到是什么导致了异常,否则我会实现了这一点。我还是一个初学者,真的。我每天都在学习语言的基本知识。