0

所以我有一个聊天室,它曾经可以工作,但我稍微更改了代码以尝试一些事情但它们没有工作,所以我试图恢复到我的原始代码,但我不确定我做错了什么,因为现在它正在抛出 NullPointerException。我的代码有一个 PrintWriters 的 ArrayList 和一个 showAll() 方法,正如它所说的那样;向聊天室中的所有人发送消息。所以基本上我想知道的是我怎么会得到例外?

    //This is the main code, used to add printwriters to the arraylist and to connect to clients
    //The Communicate thread is used to get input from users and use the showAll() method with that input
    public void listen() {
        listWriters = new ArrayList<PrintWriter>();
        try {
            scanner = new Scanner(System.in);
            portnum = getPortNumber(scanner);
            System.out.println("Listening on " + portnum);
            serverSocket = new ServerSocket(portnum);
            while(true) {
                clientcommunicate = serverSocket.accept();
                System.out.println("Connection accepted: " + clientcommunicate.toString());

                PrintWriter client = new PrintWriter(clientcommunicate.getOutputStream(), true);
                listWriters.add(client);
                Thread t = new Thread(new Communicate(clientcommunicate));
                t.start();
            }
        } catch (IOException ioe) {
            System.err.println(ioe);
            System.err.println("Error.");
            System.exit(1);
        }
    }

    //This uses a printwriter obtained in the Communicate thread; the thread initializes a socket in it with the socket obtained in the constructor
    public void showAll(String msg, PrintWriter printwriter) {
        for(int i = 0; i < listWriters.size(); i++) { //this is where the exception is thrown
            if(!listWriters.get(i).equals(printwriter)) { //if I change the paramater listWriters.size() to a regular integer like 3, and only create 2 clients or even less, the exception is thrown here instead
                listWriters.get(i).println(msg);
            }
        }
    }

编辑:

好的,所以我不再收到错误消息,但现在我似乎无法发送消息。如果我从客户端发送消息,则没有错误,但消息不会显示在任一客户端上。

4

3 回答 3

6

你被NullPointerException抛出是因为你试图取消引用(即调用方法,或从中读取字段),一个变量是null.

在这种情况下,很明显它listWriters是 null (因为它是唯一在发生异常的行上被取消引用的变量 - 查找.字符)。由于这是在您的方法中分配的listen(),因此我猜如果您在调用showAll() 之前调用会收到此错误listen()

一个非常简单的字段是在其声明中分配listWriters给一个空列表,这样它就永远不会为空:

private List<PrintWriter> listWriters = new ArrayList<PrintWriter>();

根据您的应用程序的并发要求,您可能需要做一些更详细的事情,但一般原则是您必须在尝试读取listWriters 之前进行初始化。

于 2012-10-22T11:07:39.147 回答
0

您必须在showAll方法之前调用listen方法。在您的方法之前,您没有ListWriters在您的方法中初始化。listenshowAll

于 2012-10-22T11:08:10.757 回答
0

那可能是因为,您已经初始化了您的listWriters内部listen()方法。

因此,如果您的showAll()方法在方法之前被调用listen(),它将null为您获得一个值listWriters(假设您已声明listWriters为实例变量,并且本身尚未在那里初始化)。

您可以在您声明它的地方尝试initializing它。

private List<PrintWriter> listWriters = new ArrayList<PrintWriter>();
于 2012-10-22T11:08:28.480 回答