В настоящее время я пишу Java-приложение, которое использует шаблон Singleton и сериализацию. У меня есть выделенный класс сериализатора, который сериализует и десериализует объект в заданный путь к файлу и из него. Один из моих объектов сериализован и десериализован без проблем: я делаю некоторые изменения в состоянии моего приложения, пока оно открыто, затем закрываю приложение, и эти изменения остаются, когда я снова открываю его. Тем не менее, это не работает с другим моим объектом, хотя, насколько я могу судить, между ними нет существенной разницы, которая должна быть причиной этого.
Вот код для моего класса Serialiser:
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;
}
И Учетная запись, и Сообщение поддерживают Serializable, и оба имеют serialVersionUID. Я не получаю никаких исключений NotSerializable.
Любая помощь в решении этой проблемы будет принята с благодарностью. При необходимости я могу предоставить больше кода моего приложения.