java - 序列化和反序列化具有 ArrayList 字段的类的单例实例的问题
问题描述
目前,我正在编写一个使用单例模式和序列化的 Java 应用程序。我有一个专用的序列化程序类,可以对给定文件路径的对象进行序列化和反序列化。我的一个对象被序列化和反序列化没有问题:我在应用程序打开时对其状态进行了一些更改,然后关闭应用程序,当我重新打开它时这些更改仍然存在。但是,这不适用于我的另一个对象,即使据我所知,它们之间没有重大区别应该会导致这种情况。
这是我的序列化器类的代码:
public static Boolean serialise(Object target, String filePath){
try (FileOutputStream fileOut = new FileOutputStream(filePath);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);){
objectOut.writeObject(target);
return true;
} catch (FileNotFoundException ex) {
Logger.getLogger(Serialiser.class.getName()).log(Level.SEVERE, null, ex);
return false;
} catch (IOException ex) {
Logger.getLogger(Serialiser.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
}
public static Object deserialise(String filePath){
try (FileInputStream fileIn = new FileInputStream(filePath);
ObjectInputStream objectIn = new ObjectInputStream(fileIn);){
Object readObject = objectIn.readObject();
return readObject;
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Serialiser.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
这是我的对象的相关代码。首先,一个有效的:
public class AccountManager implements Serializable {
private static final long serialVersionUID = 1L;
private static final String FILE_PATH = "data//account_manager.ser";
private static AccountManager instance;
private ArrayList<Account> accounts = null;
private AccountManager(){
accounts = new ArrayList<>();
}
public static AccountManager getInstance(){
if (instance == null){
instance = (AccountManager)Serialiser.deserialise(FILE_PATH);
if (instance == null){
instance = new AccountManager();
Serialiser.serialise(instance, FILE_PATH);
}
}
return instance;
}
现在不起作用的那个:
public class MessageManager implements Serializable {
private static final long serialVersionUID = 1L;
private static final String FILE_PATH = "data//message_manager.ser";
private static MessageManager instance = null;
private ArrayList<Message> messages = null;
private MessageManager(){
messages = new ArrayList<>();
}
public static MessageManager getInstance(){
if (instance == null){
instance = (MessageManager)Serialiser.deserialise(FILE_PATH);
if (instance == null){
instance = new MessageManager();
Serialiser.serialise(instance, FILE_PATH);
}
}
return instance;
}
本质上,这两个类的工作方式相同:它们存储特定类型的对象列表,并提供对其各自列表内容的访问和执行操作。当访问类的 Singleton 实例时,它会检查是否可以从文件中反序列化实例。如果不能,它会实例化一个新的并将其序列化。同样,这适用于其中一个 AccountManager,但不适用于另一个 MessageManager。也就是说,如果在应用程序运行时创建新的 Account 对象并使用 AccountManager 存储它,如果我重新启动应用程序,它仍然会存在。对于 MessageManager 和 Message 对象,情况并非如此。
当一个新的帐户被创建时,该实例以及可能与它相关的字段,即帐户列表被序列化。
public Account createAccount(String password, String givenName, String surname, String address, Gender gender, LocalDate dateOfBirth){
String id = IDGenerator.getInstance().generateID(AccountType.PATIENT, accounts);
Account createdAccount = null;
if (id != null){
createdAccount = new PatientAccount(id, password, givenName, surname, address, gender, dateOfBirth);
if (createdAccount != null){
accounts.add(createdAccount);
Serialiser.serialise(instance, FILE_PATH);
}
return createdAccount;
}
return null;
}
在 MessageManager 中,当一个新的 Message 实例被添加到它的列表时,该实例以及它的列表再次被序列化:
public Boolean sendMessage(Message message){
if (messages.add(message)){
Serialiser.serialise(instance, FILE_PATH);
return true;
}
return false;
}
Account 和 Message 都实现了 Serializable,并且都有 serialVersionUID。我没有得到任何 NotSerializable 异常。
任何有助于解决此问题的帮助将不胜感激。如有必要,我可以提供更多我的应用程序代码。
解决方案
我设法解决了我的问题。我的问题在我的应用程序的不同部分。本质上,我相信 MessageManager 没有被序列化,因为我无法从它那里得到我期望的数据。事实证明,问题出在返回数据的方法中:我使用对象引用来识别要返回的数据。当然,反序列化会创建新实例,因此,在重新创建对象后,我无法再访问旧实例标识的数据。
为了解决我的问题,我使用了另一种识别数据的方法:一个字符串属性,其值在反序列化之前和之后的实例之间是相同的。
感谢所有看过我的问题和/或试图回答的人。
推荐阅读
- javascript - Nuxt JS / Firebase 的 Vuex 未知操作
- android - 未插入 SIM 卡时,Unity Firebase 无法正常工作
- python - 使用 For 循环(#Tkinter)循环图像
- java - 我怀疑我的代码没有退出 while 循环
- fortran - 在 Fortran 90 中将整数向下舍入以 0 或 5 结尾
- asynchronous - 我如何根据异步调用的结果使用 Navigator?
- excel - 如何在单独的模块中将工作表添加到 vba 代码?
- java - 如何在 spring-data-rest 中使用 Pageable 作为 get-query 参数?
- python - Extracting texts from
- items with selenium in Python
- python - 如何在黄砖地块中设置图形大小?