[英]Why does this Java program throw a NullPointerException?
In this program, I need my program to put a class's status into a JTextArea that is uneditable, but I keep getting a NullPointerException. 在此程序中,我需要我的程序将类的状态放入不可编辑的JTextArea中,但是我一直在获取NullPointerException。 I have a feeling that this has something to do with the fact that the object is deserialized every time it starts. 我感觉这与对象在每次启动时都反序列化有关。 If I remove this and replace it with an actual String, it works fine. 如果我删除它并用实际的String替换它,则可以正常工作。 What do I do? 我该怎么办? I'll post both classes below. 我将在下面发布这两个课程。
BankGUI class: BankGUI类:
package GUIs;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
public class BankGUI {
BankAccount account;
private void deserializeAccount() {
try {
ObjectInputStream objectStream2 = new ObjectInputStream(
new FileInputStream("bankAccounts.txt"));
account = (BankAccount) objectStream2.readObject();
objectStream2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("");
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
BankGUI gui = new BankGUI();
gui.deserializeAccount();
gui.displayGUI();
}
// all global components for JFrame
JTextArea statusArea;
JCheckBox isLockedCheckBox;
JList depositAmount;
JList withdrawAmount;
JButton depositButton;
JButton withdrawButton;
JButton saveAccountButton;
private void displayGUI() {
JFrame frame = new JFrame("Virtual Bank v3.3");
Integer[] intList = { 1, 2, 5, 10, 20, 50 };
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
rightPanel.setBackground(Color.GREEN);
JPanel centerPanel = new JPanel();
centerPanel.setBackground(Color.GREEN);
centerPanel.setLayout(new GridBagLayout());
frame.add(BorderLayout.CENTER, centerPanel);
frame.add(BorderLayout.EAST, rightPanel);
// add some JLabel's
JLabel depositAmountLabel = new JLabel("Deposit Amount:");
JLabel withdrawAmountLabel = new JLabel("Withdraw Amount:");
JLabel isLockedLabel = new JLabel("Lock account(True/False)");
// finish components(center panel)
statusArea = new JTextArea(25, 25);
statusArea.setEditable(false);
statusArea.setText(account.status);
centerPanel.add(statusArea);
// add this to panel
isLockedCheckBox = new JCheckBox();
// add this to panel
// scrollers and Jlists
// ***********************************************************************
depositAmount = new JList(intList);
JScrollPane scroller1 = new JScrollPane(depositAmount);
scroller1
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroller1
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
depositAmount.setVisibleRowCount(1);
depositAmount.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
withdrawAmount = new JList(intList);
JScrollPane scroller2 = new JScrollPane(depositAmount);
scroller2
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroller2
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
depositAmount.setVisibleRowCount(1);
depositAmount.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// ***********************************************************************
depositButton = new JButton("Deposit Amount.");
withdrawButton = new JButton("Withdraw Amount");
saveAccountButton = new JButton("Save your Account");
rightPanel.add(depositAmount);
rightPanel.add(depositButton);
frame.setSize(425, 650);
frame.setVisible(true);
}
private void serializeAccount() {
try {
ObjectOutputStream objectStream1 = new ObjectOutputStream(
new FileOutputStream("bankAccounts.txt"));
objectStream1.writeObject(account);
objectStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BankAccount class: BankAccount类:
package GUIs;
import java.io.Serializable;
public class BankAccount implements Serializable {
private static final long serialVersionUID = -5341449653011848470L;
int balance = 0;
int userWallet = 0;
String owner = "Foo Bar";
String status = "Account Owner: " + owner + "\nAccount balance: $"
+ balance + "\nOwner Wallet Balance: $" + userWallet;
boolean isLocked = false;
public int withdraw(int amount) {
balance -= amount;
userWallet += amount;
return userWallet;
}
public int deposit(int amount) {
balance += amount;
userWallet -= amount;
return balance;
}
public int depositCashIntoWallet(int amount) {
userWallet += amount;
return userWallet;
}
}
Here's the stack trace: 这是堆栈跟踪:
Exception in thread "main" java.lang.NullPointerException
at GUIs.BankGUI.displayGUI(BankGUI.java:85)
at GUIs.BankGUI.main(BankGUI.java:49)
The stack trace almost tells you exactly what the problem is. 堆栈跟踪几乎可以告诉您确切的问题所在。 You have a NullPointerException
at line 85 in your BankGUI class. 您的BankGUI类的第85行有一个NullPointerException
。 If my IDE is correct line 85 is this line 如果我的IDE正确,则第85行是该行
statusArea.setText(account.status);
Only 2 things can be null here. 这里只有2件事可以为空。 statusArea and account. status区域和帐户。 Since you initialize statusArea
right before you use it, it must be account
. 由于您是在使用前初始化statusArea
,因此它必须是account
。
You need to initialize account before you use it. 您需要先初始化帐户,然后才能使用它。
BankAccount account = new BankAccount();
I can see you try to initialize account
in a try catch block here: 我可以看到您尝试在以下尝试捕获块中初始化account
:
try {
ObjectInputStream objectStream2 = new ObjectInputStream(
new FileInputStream("bankAccounts.txt"));
account = (BankAccount) objectStream2.readObject();
objectStream2.close();
} catch (Exception e) {
e.printStackTrace();
}
If an exception is thrown account
is not initialized. 如果引发异常,则不会初始化account
。 Make sure this does not throw an exception or make sure you check for null
before you use account
. 确保这不会引发异常,或者在使用account
之前确保检查null
。
One possibility is that the file used to serialize BankAccount
, bankAccounts.txt
, may be corrupt. 一种可能是用于序列化BankAccount
的文件bankAccounts.txt
可能已损坏。 This could have happened due to the class itself being modified. 这可能是由于类本身被修改而发生的。 In that case you could temporarily replace 在这种情况下,您可以暂时更换
account = (BankAccount) objectStream2.readObject();
with 与
account = new BankAccount();
in deserializeAccount
. 在deserializeAccount
。 This will allow the application to load without throwing an NPE
. 这将允许应用程序加载而不会抛出NPE
。
Add an ActionListener
to call serializeAccount
and re-save the file. 添加一个ActionListener
来调用serializeAccount
并重新保存文件。 The deserializeAccount
method can now be reverted and the application should be able to load the bankAccounts.txt
. 现在可以还原deserializeAccount
方法,并且应用程序应该能够加载bankAccounts.txt
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.