简体   繁体   English

Java ArrayList空指针异常

[英]Java ArrayList null pointer exception

EDIT 编辑

I've cleaned up the .equals method for string equality and changed the ContactsCollection initialization to: 我已经清理了.equals方法以实现字符串相等性,并将ContactsCollection初始化更改为:

public static ArrayList<Contact> contactList = new ArrayList<Contact>();

I've also changed the action performed method in hopes that 'Display contacts' would show more than one contact. 我还更改了执行动作的方法,希望“显示联系人”可以显示多个联系人。

    if (contactInput.equals("Display contacts"))
    {
        ContactsCollection.read();
        for (int i = 0; i < contactList.size(); i++)
        {
            contact = (Contact)contactList.get(i);
            for (int j =0; j < contactList.size(); j++)
            {
                textArea.append(contact.getName() + "," + contact.getNumber() + "\n");
            }
        }
    }

Ultimately the .dat file is written but does not contain any data that is added through the GUI. 最终,将写入.dat文件,但不包含通过GUI添加的任何数据。

END EDIT 结束编辑

I am writing a mock cellphone GUI that acts as a very basic contacts manager. 我正在编写一个模拟手机GUI,用作非常基本的联系人管理器。 There are several other classes that do not deal with the ArrayList that are working as intended. 还有其他一些无法按预期工作的ArrayList类。

When attempting to add a contact to the file I receive a null pointer exception at line 13 of the ContactsCollection class: 尝试将联系人添加到文件时,我在ContactsCollection类的第13行收到空指针异常:

for (int i = 0; i < contactList.size(); i++)

and line 93 of the Contacts (GUI) class: 和Contacts(GUI)类的第93行:

contactList.add(contact);

I have a feeling that I did something wrong when coding the Contacts and ContactsCollection classes. 我感觉在编写Contacts和ContactsCollection类时做错了什么。 I'm hoping the program to run as follows: The user clicks add contact and enters the information which becomes an object Contact and is added to the contactList ArrayList and written (serialized) to a file "contactList.dat". 我希望程序运行如下:用户单击添加联系人,然后输入成为对象联系人的信息,并将其添加到contactList ArrayList并写入(序列化)到文件“ contactList.dat”。 When the user clicks display contacts the file is read in and each contact is displayed in GUI. 当用户单击显示联系人时,将读取文件,并且每个联系人都将显示在GUI中。

I think that there are several issues with the way I set up the ArrayList, but I think I'm very close to having the program run as I had hoped. 我认为设置ArrayList的方式存在一些问题,但是我认为我已经非常接近让程序按我希望的那样运行。 Any help is greatly appreciated! 任何帮助是极大的赞赏!

Contacts class: 联系人类别:

import java.util.*;
import java.io.*;

public class Contact implements Serializable
{
public static final long serialVersionUID = 42L;
public String name, number;

Contact()
{
    name = "No name";
    number = "No number";
}

Contact (String theName, String theNumber)
{
    this.name = theName;
    this.number = theNumber;
}

public void setName(String aName)
{
    this.name = aName;
}

public void setNumber(String aNumber)
{
    this.number =aNumber;
}

public String getName()
{
    return name;
}

public String getNumber()
{
    return number;
}

public String toString()
{
    return name + ": " + number;
}

public boolean equals(Contact other)
{
   if (name.equals(other.getName()) && number.equals(other.getNumber()))
   {
      return(true);
   }
   else
   {
      return(false);
   }
}   
}

Contacts Collection class 联系人集合类

import java.io.*;
import java.util.*;

class ContactsCollection
{
public static ArrayList<Contact> contactList;

public static void write()
{
    try 
    {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("contactList.dat"));
        for (int i = 0; i < contactList.size(); i++)
        {
            out.writeObject(contactList.get(i));
        }
        out.close();
    } 
    catch(IOException e)
    {
        e.printStackTrace();
    }
}

public static void read()
{
contactList = new ArrayList<Contact>();
try
{
    ObjectInputStream in = new ObjectInputStream(new FileInputStream("contactList.dat"));
    Contact temp;
    while (in.available()!=0)
    {
        temp = (Contact)in.readObject();
        contactList.add(temp);
    }
    in.close();
}
catch(FileNotFoundException e)
{
    e.printStackTrace();
}
catch(IOException e)
{
    e.printStackTrace();
}
catch(ClassNotFoundException e)
{
    e.printStackTrace();
}       

}
}

Contacts (GUI) class 联系人(GUI)类

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

class Contacts extends JFrame implements ActionListener, WindowListener
{
public static final int WIDTH = 400;
    public static final int HEIGHT = 600;
    public static final int SMALL_WIDTH = 200;
    public static final int SMALL_HEIGHT = 100;

private static final Dimension stdBtn = new Dimension(150, 50);    

    JPanel centerPanel, northPanel, southPanel;
ImageIcon icon;
JLabel picture;
JButton addContact, displayContacts;
JScrollPane scroll;
JTextArea textArea;
Clock clock;
Background background;
Contact contact;
ArrayList<Contact> contactList;


public Contacts()
{
    super("Contacts");
    this.setLayout(new BorderLayout());
    this.setSize(WIDTH, HEIGHT);
    this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    addWindowListener(this);
    this.setLocationRelativeTo(null);

    centerPanel = new JPanel();
    northPanel = new JPanel();
    southPanel = new JPanel();

    centerPanel.setBackground(Color.BLACK);
    southPanel.setBackground(Color.BLACK);      

    clock = new Clock();
    northPanel.add(clock);

    icon = new ImageIcon("ContactsBackground.jpg");
    picture = new JLabel(icon);
    centerPanel.add(picture);

    textArea = new JTextArea("", 10, 30);
    textArea.setEditable(false);
    JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);    
    centerPanel.add(scroll);    

    JButton displayContacts = new JButton("Display contacts");
    displayContacts.addActionListener(this);
    southPanel.add(displayContacts);

    JButton addContact = new JButton("Add contact");
    addContact.addActionListener(this);
    southPanel.add(addContact);

    this.add(northPanel, BorderLayout.NORTH);
    this.add(centerPanel, BorderLayout.CENTER);
    this.add(southPanel, BorderLayout.SOUTH);       

    setResizable(false);        
}

public void actionPerformed(ActionEvent e)
{
    contactList = new ArrayList<Contact>();
    JButton source = (JButton)e.getSource();
    String contactInput = source.getText();

    if (contactInput == "Display contacts")
    {
        ContactsCollection.read();
        for (int i = 0; i < contactList.size(); i++)
        {
            contact = (Contact)contactList.get(i);
            textArea.setText(contact.getName() + "," + contact.getNumber() + "\n");
        }
    }
    if (contactInput == "Add contact")
    {
        String name = JOptionPane.showInputDialog(null, "Enter Name");
        String number = JOptionPane.showInputDialog(null, "Enter Number");
        contact = new Contact(name, number);
        contactList.add(contact);
        ContactsCollection.write();
    }
}

public void windowOpened(WindowEvent e)
{}

public void windowClosing(WindowEvent e)
{
    this.setVisible(false);
    background = new Background();
    background.setVisible(true);        
}

public void windowClosed(WindowEvent e)
{}

public void windowIconified(WindowEvent e)
{}

public void windowDeiconified(WindowEvent e)
{}

public void windowActivated(WindowEvent e)
{}

public void windowDeactivated(WindowEvent e)
{}      
}

Change 更改

public static ArrayList<Contact> contactList;

to

public static ArrayList<Contact> contactList = new ArrayList<>();

in your version contactList is null because you never initialize it and in the write() method you are trying to call size() on it. 在您的版本中, contactListnull因为您从未对其进行初始化,并且在write()方法中尝试在其上调用size()


Also, there are some serious flaws in your GUI class (in the actionPerformed() method), read this question to fix them: How do I compare strings in Java? 另外,您的GUI类(在actionPerformed()方法中)也存在一些严重的缺陷,请阅读此问题以修复它们: 如何在Java中比较字符串?


Also remember that textArea.setText(...) will set the complete text for the textArea , so because this is in a loop in your code, the textArea will contain the output of the last iteration of that loop only. 还记得textArea.setText(...)将设置为完整的文本textArea ,所以因为这是在你的代码的循环,在textArea将只包含循环的最后一次迭代的输出。 In your case it will be only the last contact. 就您而言,这只是最后一次联系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM