Entonces... Tenemos una clase que queremos serializar usando métodos convencionales (usamos
Serializable
)
package Serialization;
import java.io.Serializable;
public class SerializableClass implements Serializable {
private String name;
private int number;
}
Estamos escribiendo una aplicación de prueba. Diré de inmediato que mi objetivo es mostrar qué serialVersionUID
.
package Serialization;
import java.io.*;
public class MainSerializable {
final static String FILE_NAME = "c:\\File.dat";
public static void serialize(Object object) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(object);
fileOutputStream.close();
objectOutputStream.close();
}
public static Object deserialize() throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream(FILE_NAME);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object object = objectInputStream.readObject();
objectInputStream.close();
return object;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializableClass serializableClass = new SerializableClass();
serialize(serializableClass);
SerializableClass newObject = (SerializableClass) deserialize();
}
}
Todo funciona muy bien. La clase se serializa en un archivo FILE_NAME = "c:\\File.dat"
. Estaba oscureciendo... :) Olvidé agregar campos a la clase. Agregar:
public class SerializableClass implements Serializable {
private String name;
private int number;
private String FirstName; // +
private String LastName; // +
}
Todo parece estar bien... todo se compila... Así que lo ejecutamos main
, deserializamos la clase SerializableClass
del archivo " c:\\File.dat
":
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializableClass newObject = (SerializableClass) deserialize();
}
Ah... que hacer...
Exception in thread "main" java.io.InvalidClassException: Serialization.SerializableClass; local class incompatible: stream classdesc serialVersionUID = 8129437039424566964, local class serialVersionUID = -8271479231760195917
at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
at Serialization.MainSerializable.deserialize(MainSerializable.java:22)
at Serialization.MainSerializable.main(MainSerializable.java:30)
En general todo bien. La clase ha cambiado y es serialVersionUID
= -8271479231760195917
, y se ha serializado en el archivo serialVersionUID
= 8129437039424566964
. ¿Qué hacer ahora, qué hacer? ¿Cómo crear una instancia? Hay una salida. Necesitamos declarar en nuestra clase: static final long serialVersionUID
, que es igual a serialVersionUID
la clase :) atenuada en el archivo. Aquellos. dijimos, adelante, deserializaré... puedes... tus versiones son las mismas:
package Serialization;
import java.io.Serializable;
public class SerializableClass implements Serializable {
static final long serialVersionUID = 8129437039424566964L;
private String name;
private int number;
private String FirstName; // +
private String LastName; // +
}
Lanzamos... Y... Todo funciona. Según tengo entendido, este error se podría haber evitado si la clase hubiera declarado de antemano:
public class SerializableClass implements Serializable {
static final long serialVersionUID = 1L;
private String name;
private int number;
}
Aquellos. No permitimos que Java haga sus propios cálculos serialVersionUID
basados en sus algoritmos (algoritmos bastante complejos). Ahora, cada vez que cambia una clase, verificamos serialVersionUID = 1L
:
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializableClass serializableClass = new SerializableClass();
serialize(serializableClass);
SerializableClass newObject = (SerializableClass) deserialize();
}
Funciona... Y ahora así:
public class SerializableClass implements Serializable {
static final long serialVersionUID = 1L;
//private String name;
//private int number;
}
Sí.. ¿Y entonces?
public class SerializableClass implements Serializable {
static final long serialVersionUID = 1L;
public int A;
protected String value;
//private String name;
//private int number;
}
Genial... todo sigue funcionando. Entonces terminé mi primer artículo. Quería poner todo esto en los comentarios, pero no pude leer los símbolos. Aceptaré críticas y comentarios sobrios. PD: Gracias al autor que me inspiró a hacer estas delicias. Probablemente así aprenden :) Buena suerte a todos :)
GO TO FULL VERSION