Java空指针异常求助:ArrayList赋值调用get方法时出错
你碰到的java.lang.NullPointerException核心原因很明确:PaymentScreenController里的tbl变量根本没被初始化,它的值是null,调用null.getCustomers()肯定会触发空指针异常。
为什么会出现这个问题?
看你的代码,PaymentScreenController里只是声明了public Table tbl;,但既没有用new Table()创建实例,也没有通过FXML的fx:id绑定给它赋值。更关键的是,提交订单代码里的tbl是另一个控制器里的实例,和PaymentScreenController里的tbl完全不是同一个对象——这就导致你在支付页面控制器里根本拿不到之前添加的客户订单数据。
具体解决方案
我给你两种常用的解决思路,你可以根据自己的业务场景选择:
方案1:把Table设计成单例类(推荐,适合全局共享订单数据)
因为整个应用里应该只有一个Table实例来管理所有客户订单,把Table改成单例后,任何控制器都能拿到同一个实例,不会出现实例不匹配的问题。
首先修改Table类:
public class Table { // 单例实例 private static Table instance; // 初始化客户列表,避免getCustomers()返回null private ArrayList<Customer> customers = new ArrayList<>(); // 私有构造方法,禁止外部直接new private Table() {} // 获取单例的方法 public static Table getInstance() { if (instance == null) { instance = new Table(); } return instance; } public ArrayList<Customer> getCustomers() { return customers; } }
然后修改PaymentScreenController的initialize()方法:
public class PaymentScreenController { public ArrayList<Customer> allcustomers; @FXML public void initialize() { // 获取Table单例实例 Table tbl = Table.getInstance(); allcustomers = tbl.getCustomers(); System.out.println(tbl.getCustomers()); System.out.println("test"); for (Customer customer : allcustomers) { System.out.println(customer.getCustomerorder()); } } }
最后修改提交订单的代码,改用单例:
public void submitorder(ActionEvent actionEvent) throws IOException { Customer cust = new Customer(); cust.getCustomerorder().addAll(order); // 获取Table单例,添加客户 Table.getInstance().getCustomers().add(cust); System.out.println(Table.getInstance().getCustomers()); lvOrder.getItems().clear(); if (Table.getInstance().getCustomers().size() == noOfDiners) { Window mainWindow = btnSubmitOrder.getScene().getWindow(); Parent newRoot = FXMLLoader.load(getClass().getResource("payment_screen.fxml")); mainWindow.getScene().setRoot(newRoot); } }
方案2:手动传递Table实例到PaymentScreenController
如果不想用单例,你可以在切换到支付页面时,把当前的Table实例直接传给PaymentScreenController:
修改提交订单的代码:
public void submitorder(ActionEvent actionEvent) throws IOException { Customer cust = new Customer(); cust.getCustomerorder().addAll(order); tbl.getCustomers().add(cust); System.out.println(tbl.getCustomers()); lvOrder.getItems().clear(); if (tbl.getCustomers().size() == noOfDiners) { Window mainWindow = btnSubmitOrder.getScene().getWindow(); // 不要直接用FXMLLoader.load(),先创建loader实例 FXMLLoader loader = new FXMLLoader(getClass().getResource("payment_screen.fxml")); Parent newRoot = loader.load(); // 获取支付页面控制器,传递tbl实例 PaymentScreenController paymentController = loader.getController(); paymentController.tbl = this.tbl; mainWindow.getScene().setRoot(newRoot); } }
同时要确保Table类的构造方法初始化客户列表,避免返回null:
public class Table { private ArrayList<Customer> customers; public Table() { // 初始化列表 customers = new ArrayList<>(); } public ArrayList<Customer> getCustomers() { return customers; } }
额外注意点
别忘记检查Customer类的getCustomerorder()方法,确保它返回的列表不是null——最好在Customer的构造方法里初始化订单列表:
public class Customer { private ArrayList<Order> customerorder; public Customer() { customerorder = new ArrayList<>(); } public ArrayList<Order> getCustomerorder() { return customerorder; } }
内容的提问来源于stack exchange,提问作者jack1856

