Estoy utilizando la interfaz Java Serializable
y ObjectOutputStream
para serializar objetos (hasta ahora, este método ha sido suficiente para mis propósitos).¿La serialización preserva la identidad del objeto?
Mi API se basa en la identidad del objeto para algunas operaciones y me pregunto si se conservará por serialización. Es decir: si, para dos objetos arbitrarios a
y b
, contiene a == b
antes de la serialización, ¿se retiene después de la deserialización?
He encontrado algunos textos que claim the contrary - pero o bien escribieron sobre una versión anterior de JRE (estoy interesado solo en 1.6 y quizás 1.5), o estaban preocupados con RMI (que no es relevante para mí)
La documentation no es muy próxima a la identidad del objeto. Un technical article en sun.com menciona que ObjectOutputStream
usa el almacenamiento en memoria caché en objetos, lo cual para mí solo tiene sentido si la identidad del objeto está efectivamente preservada, pero no tengo la confianza suficiente para confiar en esta evidencia endeble.
Lo he intentado salir (Java 1.6, OS X) y encontraron que sí, la identidad de los objetos se mantiene sin cambios por la serialización. ¿Pero puedo extrapolar de estos resultados o no son confiables?
Para mi prueba, he serializa el gráfico siguiente objeto:
C----------+
| b1 b2 |
+----------+
| |
v v
B---+ B---+
| a | | a |
+---+ +---+
\ /
\/
\/
A----+
| |
+----+
Un código reproducción mínima:
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);
}
}
Si mantiene que a == b entonces no son objetos arbitrarios. Creo que tu pregunta va por las referencias. –