目前,我正在编写一个使用Singleton模式和序列化的Java应用程序。我有一个专用的序列化程序类,可将对象与给定文件路径进行序列化和反序列化。我的对象之一已被序列化和反序列化,没有任何问题:在打开应用程序的状态时,我对其进行了一些更改,然后关闭了应用程序,而当我重新打开它时,这些更改仍然存在。但是,这对我的另一个对象不起作用,即使据我所知,它们之间没有重大差异也应该导致这种情况。
这是我的Serializer类的代码:
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对象,情况并非如此。
创建新帐户后,实例及其大概关联的字段(即 accounts 列表)将被序列化。
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;
}
帐户和消息均实现可序列化,并且都具有serialVersionUID。我没有任何不可序列化的异常。
在解决此问题方面的任何帮助将不胜感激。如有必要,我可以提供更多我的应用程序代码。
答案 0 :(得分:0)
我设法解决了我的问题。我的问题出在我申请的另一部分。本质上,我认为MessageManager不会被序列化,因为我无法从中获取期望的数据。事实证明,问题出在返回数据的方法中:我正在使用对象引用来标识要返回的数据。当然,反序列化会创建新的实例,因此,在重新创建对象之后,我将无法再访问由旧实例标识的数据。
为了解决我的问题,我使用了另一种识别数据的方式:一个字符串属性,其值在反序列化之前和之后在各个实例中都是相同的。
感谢所有看过我的问题和/或试图回答我的问题的人。