有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

PrintWriter[]数组Java中的NullPointerException

我有一个问题,我已经想了好几天了

简单代码概述(伪代码):

1-当用户连接时,为他创建一个PrintWriter

2-将PrintWriter对象存储到PrintWriter[]数组中

3-增加连接的用户数

我有什么问题

  • 编译器抛出NullPointerException

是什么导致了NPE

  • 当在mainWindow类中创建的对象调用sendMessage()方法时,如果PrintWriter数组为空,我不知道是什么导致它为空,因为所有变量和数组都有静态修饰符,PrintWriter[]数组在构造函数中获得一个值(当用户连接时)

  • 在ServerHandler构造函数中,当我尝试向客户端发送消息时,它工作正常,我可以看到PrintWriter[]数组不是空的,但是当我从mainWindow实例调用sendMessage()方法时,数组是空的,userCounter整数变量仍然是0

我试过怎么解决它

  • 将variebles和数组修饰符设置为volatile和static
  • 一遍又一遍地从头开始编写所有代码

服务器类(工作正常):

package homeControl;

import java.net.*;
import java.util.Scanner;
import java.io.*;
import java.awt.*;

public class Server{
String sporocilo = null;
int id = 0;

outputHelper o = new outputHelper();


public void sprejmiPovezavo()
{
    try
    {
        ServerSocket svrSock = new ServerSocket(5000);

        while(true){

        Socket klientSocket = svrSock.accept();


        new Thread(new ServerHandler(klientSocket)).start();

        }


    }catch(IOException ex)
    {
        ex.printStackTrace();
    }
}


    public static void main(String[] args){
Server svr = new Server();
svr.sprejmiPovezavo();
}

}

ServerHandler类(此类导致问题)

package homeControl;

import java.net.*;
import java.util.ArrayList;
import java.io.*;
import java.awt.*;

public class ServerHandler implements Runnable{
static PrintWriter pw;
static PrintWriter[] writerHolder = new PrintWriter[10];
static int userCounter;
static int selectedID;


public ServerHandler(Socket socket){
    try{
        pw = new PrintWriter(socket.getOutputStream());
        writerHolder[userCounter] = pw;

        // Testing if this writerHolder[] can send the message to the client.
        writerHolder[userCounter].println("autoSent - Testint!");
        writerHolder[userCounter].flush();

        userCounter++;// Increment the number of people connected

        //Testing the values of the variables.
        System.out.println("ORG!\nuserCounter:" + userCounter +  "\nwriterHolder[userCounter]" + writerHolder[0]);
    }catch(Exception ex)
    {
        ex.printStackTrace();
    }
}
public ServerHandler()
{
    // Empty constructor
    // Used so that i don't need to pass a Socket into the class when i create a ServerHandler object from the mainWindow.class...
}



public void sendMessage(int tempID, String messageToBeSent)
{   // Testing the values of variables at the time that this method gets called.
    System.out.println("tempID:" + tempID + "\n" + "messageToBeSent:" +       messageToBeSent + "\n" + "userCounter:" + userCounter + "\n" + "selectedID:" + selectedID); 
    // End of test/Actual code:
    writerHolder[tempID].println(messageToBeSent);
    writerHolder[tempID].flush();
}

public void run()
{

}

}

mainWindows类(调用sendMessage()方法的地方)

package homeControl;

import java.awt.*;
import java.io.*;
import java.net.Socket;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.JButton;

public class mainWindow extends JFrame {

private JPanel contentPane;
private JTextField messageTextField;

ServerHandler svr = new ServerHandler(); // Thats why i use the empty constuctor in ServerHandler.class.
outputHelper o = new outputHelper();
int ID;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                mainWindow frame = new mainWindow();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public mainWindow() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);

    JMenuBar menuBar = new JMenuBar();
    setJMenuBar(menuBar);

    JMenu mnOptions = new JMenu("Options");
    menuBar.add(mnOptions);

    JMenu mnId = new JMenu("ID");
    menuBar.add(mnId);

    JMenuItem idEnaItem = new JMenuItem("ID: 0");
    mnId.add(idEnaItem);

    JMenuItem idDvaItem = new JMenuItem("ID: 1");
    mnId.add(idDvaItem);

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    messageTextField = new JTextField();
    messageTextField.setBounds(10, 209, 292, 20);
    contentPane.add(messageTextField);
    messageTextField.setColumns(10);

    JButton sendButton = new JButton("Send");
    sendButton.setBounds(312, 208, 89, 23);
    contentPane.add(sendButton);
    sendButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){

            if(event.getActionCommand() != null)
            { // Calling the sendMessage() in the ServerHandler.class which should send a message to the Client.
               svr.sendMessage(ID,messageTextField.getText());
            }

        }
    });
}
}

测试PrintWriter时ServerHandler构造函数的输出:

组织

用户计数器:1

writerHolder[userCounter]java。伊奥。PrintWriter@798c668c

手动尝试发送消息时,从SendMessage方法输出:

messageToBeSent:dsda

用户计数器:0

selectedID:0

错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at homeControl.ServerHandler.sendMessage(ServerHandler.java:45)
at homeControl.mainWindow$2.actionPerformed(mainWindow.java:84)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

共 (2) 个答案

  1. # 1 楼答案

    据我所知,这就是问题所在(在服务器中):

    new Thread(new ServerHandler(klientSocket)).start();
    

    在这里,您正在创建一个新的ServerHandler。这与在mainWindow中创建的ServerHandler的实例完全不同。所以由Server创建的一个将以一个填充的PrintWriter数组结束。。。你在mainWindow中创建的那个总是有一个空元素值数组

    你应该有一个ServerHandler实例,它是mainWindowServer共享的

  2. # 2 楼答案

    在你的mainWindow()课上,你有

    ServerHandler svr = new ServerHandler(); // Thats why i use the empty constuctor in ServerHandler.class.
    

    调用空构造函数,该构造函数不在PrintWriter[]中设置任何PrintWriter实例

    public ServerHandler()
    {
        // you don't initialize any array elements
    }
    

    然后通过访问

    writerHolder[tempID].println(messageToBeSent);
    writerHolder[tempID].flush();
    

    数组中的单元化元素,导致NPE


    而且,您的mainWindowServer类是完全不相交的。他们之间没有关系。应该有吗