Я использую интерфейс Java Serializable
и ObjectOutputStream
для сериализации объектов (до сих пор этого метода было достаточно для моих целей).
Мой API полагается на идентификацию объекта для некоторых операций, и мне интересно, будет ли он сохранен при сериализации. То есть: , если для двух произвольных объектов a
и b
он содержит a == b
до сериализации, он все еще сохраняется после десериализации?
Я нашел несколько текстов, которые утверждают обратное - но они либо написали о более старой версии JRE (меня интересует только 1.6 и, возможно, 1.5), либо были связаны с RMI ( что для меня не актуально).
Документация не очень готова к идентификации объекта. В технической статье на sun.com упоминается, что ObjectOutputStream
использует кэширование объектов, что для меня имеет смысл только в том случае, если идентичность объекта действительно сохраняется, но я не достаточно уверен, чтобы полагаться на это неубедительное доказательство.
Я опробовал его (Java 1.6, OS X) и обнаружил, что yes , идентичность объектов остается неизменной при сериализации . Но могу ли я экстраполировать эти результаты или они ненадежны?
Для моего теста я сериализовал следующий граф объектов:
C----------+
| b1 b2 |
+----------+
| |
v v
B---+ B---+
| a | | a |
+---+ +---+
\ /
\ /
\/
A----+
| |
+----+
Минимальный код воспроизведения:
import java.io.*;
public class SerializeTest {
static class A implements Serializable {}
static class B implements Serializable {
final A a;
public B(A a) {
this.a = a;
}
}
static class C implements Serializable {
final B b1, b2;
public C() {
A object = new A();
b1 = b2 = new B(object);
}
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
C before = new C();
System.out.print("Before: ");
System.out.println(before.b1.a == before.b2.a);
// Serialization.
ByteArrayOutputStream data = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(data);
out.writeObject(before);
out.close();
// Deserialization.
ObjectInputStream in =
new ObjectInputStream(new ByteArrayInputStream(data.toByteArray()));
C after = (C) in.readObject();
System.out.print("After: ");
System.out.println(after.b1.a == after.b2.a);
}
}