尝试访问不为空的 Java ArrayList<User> 时出现 NullPointer
Posted
技术标签:
【中文标题】尝试访问不为空的 Java ArrayList<User> 时出现 NullPointer【英文标题】:NullPointer when trying to access a Java ArrayList<User> that is NOT null 【发布时间】:2019-08-10 00:30:22 【问题描述】:我的 UserController 中有一个 ArrayList,用于存储我的所有 User 实例。
我可以使用我的 setUserList 成功设置 ArrayList,因为我可以使用 currentUser.getFirstName() 循环并打印用户的名字
我从一个 JavaFX 按钮触发了我的登录功能,并且在尝试打印 ArrayList 的大小时收到了 NullPointer 异常,该大小之前的大小为 1 并打印了用户的名字。
用户控制器:
public class UserController
public ArrayList<User> userList; //should contain one user thomas but gives null pointer
//static ArrayList<User> userList; //this does not return a null pointer
public void setUserList(ArrayList list)
userList = list;
for (User user : userList)
User currentUser = (User) user;
String firstName = currentUser.getFirstName();
System.out.println("Users in the UserController: " + firstName); //prints the user thomas
public void login()
try
System.out.println(userList.size()); //null pointer
catch (Exception e)
System.out.println(e);
包含登录方法的用户界面
public class UserInterface extends Application
User loggedInUser;
UserRepo userRepo = new UserRepo();
UserController userController = new UserController();
Connection conn;
//login.fxml
@FXML
public TextField InputEmailAddress;
@FXML
public TextField InputPassword;
@Override
public void start(Stage stage) throws Exception
String connectionURL = "jdbc:derby://localhost:1527/gymManager";
String userName = "root";
String userPassword= "root";
try
conn = DriverManager.getConnection(connectionURL, userName, userPassword);
if(conn != null)
System.out.println("Connected to the database");
ArrayList<User> list = userRepo.read(conn);
userController.setUserList(list); //here is where I set the ArrayList<Users> in the USerController
Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
catch(SQLException e)
System.out.println("Exception:" + e.toString());
public static void main(String[] args)
launch(args);
public void login(ActionEvent event) throws Exception
userController.login();
login.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0" prefWidth="1080.0" styleClass="main-pane" xmlns:fx="http://javafx.com/fxml/1" fx:controller="classmanager.UserInterface">
<children>
<Button fx:id="loginButton" layoutX="583.0" layoutY="451.0" onAction="#login" mnemonicParsing="false" prefHeight="56.0" prefWidth="191.0" text="Log In">
<font>
<Font name="Montserrat Regular" size="13.0" />
</font>
<styleClass>
<String fx:value="white-btn" />
<String fx:value="bg-blue" />
<String fx:value="rounded-btn" />
</styleClass></Button>
<Button layoutX="784.0" layoutY="451.0" mnemonicParsing="false" prefHeight="56.0" prefWidth="158.0" text="I'm new here">
<font>
<Font name="Montserrat Regular" size="13.0" />
</font>
<styleClass>
<String fx:value="outline-btn" />
<String fx:value="rounded-btn" />
</styleClass></Button>
<Button layoutX="563.0" layoutY="514.0" mnemonicParsing="false" prefHeight="38.0" prefWidth="231.0" styleClass="transparent-btn" text="I've forgotten my password">
<font>
<Font name="Montserrat Regular" size="13.0" />
</font></Button>
<Label layoutX="581.0" layoutY="273.0" prefHeight="18.0" prefWidth="411.0" text="Book classes and manage your membership details here" textFill="#9a9a9a">
<font>
<Font name="Montserrat Regular" size="14.0" />
</font>
</Label>
<Label layoutX="577.0" layoutY="180.0" prefHeight="18.0" prefWidth="353.0" text="Welcome to the" textFill="#1a73b5">
<font>
<Font name="Montserrat Medium" size="30.0" />
</font>
</Label>
<Label layoutX="577.0" layoutY="217.0" prefHeight="50.0" prefWidth="411.0" text="Village Hotel Gym" textFill="#1a73b5">
<font>
<Font name="Montserrat Medium" size="40.0" />
</font>
</Label>
<ImageView fitHeight="730.0" fitWidth="544.0" layoutX="-25.0" layoutY="-4.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../login-banner.jpg" />
</image>
</ImageView>
<TextField fx:id="InputEmailAddress" layoutX="581.0" layoutY="325.0" prefHeight="50.0" prefWidth="386.0" promptText="Email address" styleClass="login-input">
<opaqueInsets>
<Insets left="20.0" />
</opaqueInsets>
<font>
<Font name="Montserrat Regular" size="13.0" />
</font>
</TextField>
<TextField fx:id="InputPassword" layoutX="581.0" layoutY="384.0" prefHeight="50.0" prefWidth="386.0" promptText="Password" styleClass="login-input">
<opaqueInsets>
<Insets left="20.0" />
</opaqueInsets>
<font>
<Font name="Montserrat Regular" size="13.0" />
</font>
</TextField>
</children>
</Pane>
我简直无法理解为什么 UserController 类中的一个方法(setUserList)会告诉我 ArrayList 包含 1 个用户,而另一个(登录)会返回一个 NullPointer
感谢任何提示
【问题讨论】:
您的 ArrayList 在该函数中不可访问。你必须把它变成静态的 可能您在UserController
的一个实例上调用setUserList
,然后在另一个实例上调用login
。从您的代码中不清楚userController
值来自何处以及调用UserController
方法login
的哪个实例。
因此可以在不同功能之间共享一份副本
同意@MikhailVladimirov。或者您在调用setUserList
之前为同一实例调用login()
。
您好,感谢您这么快回来。我已经更新了问题以显示完整的 UserInterface 类。据我所知,setUserList 和 login 都在同一个 userController 实例上调用
【参考方案1】:
请像这样更改您的用户控制器,看看它是否工作:
public class UserController
public ArrayList<User> userList = new ArrayList<>(); //should contain one user thomas but gives null pointer
//static ArrayList<User> userList; //this does not return a null pointer
public void setUserList(ArrayList list)
userList.addAll(list);
for (User user : userList)
User currentUser = (User) user;
String firstName = currentUser.getFirstName();
System.out.println("Users in the UserController: " + firstName); //prints the user thomas
public void login()
try
System.out.println(userList.size()); //null pointer
catch (Exception e)
System.out.println(e);
【讨论】:
您好,感谢您的评论。您的修复删除了 NullPointer,尽管 userList 的大小在应该为 1 时仍然为 0。 setUserList 中的 list.size() = 1,但登录函数中的 userLisr.size() = 0 在您的UserInterface
中是否可以在userController.setUserList(list);
之前调用public void login(ActionEvent event) throws Exception
方法?【参考方案2】:
我敢打赌,UserInterface
的另一个实例是在 fxml 加载时创建的,所以你有另一个 UserController
的空实例。使用您的 UserController
作为 login.fxml 的控制器。
-
将
fx:controller
设置为UserController
(我猜类在同一个包中)。
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0" prefWidth="1080.0" styleClass="main-pane" xmlns:fx="http://javafx.com/fxml/1" fx:controller="classmanager.UserController">
-
将 TextFields 声明移至
UserController
:
public class UserController
public ArrayList<User> userList; //should contain one user thomas but gives null pointer
//static ArrayList<User> userList; //this does not return a null pointer
//login.fxml
@FXML
public TextField InputEmailAddress;
@FXML
public TextField InputPassword;
...
-
不要在
UserInterface
中实例化userController
:
public class UserInterface extends Application
User loggedInUser;
UserRepo userRepo = new UserRepo();
UserController userController;
Connection conn;
-
更改
UserInterface#start()
:
public void start(Stage stage) throws Exception
String connectionURL = "jdbc:derby://localhost:1527/gymManager";
String userName = "root";
String userPassword= "root";
try
conn = DriverManager.getConnection(connectionURL, userName, userPassword);
if(conn != null)
System.out.println("Connected to the database");
ArrayList<User> list = userRepo.read(conn);
FXMLLoader loader = new FXMLLoader(getClass().getResource("login.fxml"));
Parent root = loader.load();
userController = loader.getController();
userController.setUserList(list);
...
-
从
UserInterface
中删除login()
方法并在UserController
中重写login()
,如下所示:
@FXML
protected void login(ActionEvent event)
try
System.out.println(userList.size()); //null pointer
catch (Exception e)
System.out.println(e);
【讨论】:
以上是关于尝试访问不为空的 Java ArrayList<User> 时出现 NullPointer的主要内容,如果未能解决你的问题,请参考以下文章