#java #deserialization
#java #десериализация
Вопрос:
Я написал два простых тестовых примера Junit, один для serailize, а другой для десериализации. Когда я запустил два тестовых примера одновременно, десериализация сработала и выдала мне правильный вывод сохраненного значения, равного 20. НО когда я запускал тестовые примеры один за другим (или вы можете запустить программу и сериализовать, а затем запустить программу просто для десериализации), я получаю другой хэш-код и другое сохраненное значение, равное 10.
public class SerializedSingletonClass implements Serializable{
/**
*
*/
private static final long serialVersionUID = 10L;
private int value = 10;
private static class SingletonHolder{
private static SerializedSingletonClass ref = new SerializedSingletonClass();
}
public static SerializedSingletonClass getObject() {
return SingletonHolder.ref;
}
public Object readResolve() {
return SingletonHolder.ref;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Мои тестовые примеры должны запускаться по одному (например, вы начинаете сериализацию, а затем снова начинаете десериализацию)
public void breakingSingleton_of_SerializedSingletonClass_with_serialization() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(
"serialized.ser"));
SerializedSingletonClass ref = SerializedSingletonClass.getObject();
ref.setValue(20);
oos.writeObject(ref);
System.out.println(ref.hashCode());
oos.close();
}
Десериализовать тестовый пример
@Test
public void test() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(
"serialized.ser"));
SerializedSingletonClass ref2 = (SerializedSingletonClass) ois.readObject();
ois.close();
System.out.println(ref2.hashCode());
System.out.println(ref2.getValue());
}
Вывод: я получаю другой хэш-код и значение, равное 10.
Вопрос: Как правильно десериализовать?
Комментарии:
1. Вы не реализуете стабильное переопределение hashCode(), поэтому Java использует значение по умолчанию, которое основано на местоположении объекта при его создании ( srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30 /… ). Если вам нужен стабильный хэш-код, вы должны определить его самостоятельно.
2. Спасибо за понимание hascode. и для десериализации я нашел виновника. Проблема заключалась в readResolve(), я узнал, что когда вы предоставляете readResolve (), он действует на экземпляр, только что созданный с помощью сериализации. Итак, в моем случае, я подозреваю, что, поскольку при втором запуске не было создано ни одного экземпляра, он создает один и присваивает значение 10, а затем десериализует его значением 10. Удаление readResolve() решило проблему.