Introducción
La serialización es la conversión del Estado de un objeto en un flujo de bytes; la deserialización hace lo contrario. Dicho de otra manera, la serialización es la conversión de un objeto Java en un flujo estático (secuencia) de bytes que luego se pueden guardar en una base de datos o transferir a través de una red.
serialización y deserialización
El proceso de serialización es independiente de la instancia, i. e., los objetos pueden ser serializados en una plataforma y deserializados en otra. Las clases que son elegibles para serialización necesitan implementar una interfaz de marcador especial Serializable.
tanto ObjectInputStream como ObjectOutputStream son clases de alto nivel que extienden java.io.InputStream y java.io.OutputStream respectivamente. ObjectOutputStream puede escribir tipos primitivos y gráficos de objetos en un OutputStream como un flujo de bytes. Estas secuencias se pueden leer posteriormente utilizando ObjectInputStream.,
El método más importante en ObjectOutputStream es:
public final void writeObject(Object o) throws IOException;
que toma un objeto serializable y lo convierte en una secuencia (flujo) de bytes. Del mismo modo, el método más importante en ObjectInputStream es:
public final Object readObject() throws IOException, ClassNotFoundException;
que puede leer un flujo de bytes y convertirlo de nuevo en un objeto Java. Esto puede ser lanzado de nuevo al objeto original.
ilustremos la serialización con una clase Person. Tenga en cuenta que los campos estáticos pertenecen a una clase (A diferencia de un objeto) y no están serializados., Además, tenga en cuenta que podemos usar la palabra clave transient para ignorar los campos de clase durante la serialización:
public class Person implements Serializable { private static final long serialVersionUID = 1L; static String country = "ITALY"; private int age; private String name; transient int height; // getters and setters}
la prueba a continuación muestra un ejemplo de guardar un objeto de tipo Person en un archivo local y luego leer este valor de nuevo en:
utilizamos ObjectOutputStream para guardar el estado de este objeto en un archivo utilizando FileOutputStream. El archivo «yourfile.txt » se crea en el directorio del proyecto. Este archivo se carga con FileInputStream. ObjectInputStream recoge esta secuencia y la convierte en un nuevo objeto llamado p2.,
finalmente, probamos el estado del objeto cargado, y coincide con el estado del objeto original.
tenga en cuenta que el objeto cargado tiene que ser lanzado explícitamente a un tipo de persona.
Java Serialización Advertencias
Hay algunas advertencias que se refieren a la serialización en Java.
3.1. Herencia y composición
Cuando una clase implementa la interfaz java.io.Serializable, todas sus subclases también son serializables., Por el contrario, cuando un objeto tiene una referencia a otro objeto, estos objetos deben implementar la interfaz Serializable por separado, o de lo contrario se lanzará una NotSerializableException:
public class Person implements Serializable { private int age; private String name; private Address country; // must be serializable too}
si uno de los campos en un objeto serializable consiste en una matriz de objetos, entonces todos estos objetos también deben ser serializables, o de lo contrario se lanzará una NotSerializableException.
3.2. Versión Serial uid
la JVM asocia un número de versión (largo) con cada clase serializable., Se utiliza para verificar que los objetos guardados y cargados tienen los mismos atributos y, por lo tanto, son compatibles en la serialización.
este número puede ser generado automáticamente por la mayoría de los IDE y se basa en el nombre de la clase, sus atributos y los modificadores de acceso asociados. Cualquier cambio resulta en un número diferente y puede causar una InvalidClassException.
si una clase serializable no declara un serialVersionUID, la JVM generará uno automáticamente en tiempo de ejecución., Sin embargo, es muy recomendable que cada clase declare su serialVersionUID ya que el generado depende del compilador y por lo tanto puede resultar en InvalidClassExceptions inesperados.
3.3. Serialización personalizada en Java
Java especifica una forma predeterminada en la que los objetos pueden ser serializados. Las clases Java pueden anular este comportamiento predeterminado. La serialización personalizada puede ser particularmente útil cuando se intenta serializar un objeto que tiene algunos atributos no serializables., Esto se puede hacer proporcionando dos métodos dentro de la clase que queremos serializar:
private void writeObject(ObjectOutputStream out) throws IOException;
y
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
con estos métodos, podemos serializar esos atributos no serializables en otras formas que se pueden serializar:
public class Address { private int houseNumber; // setters and getters}
la siguiente prueba unitaria prueba esta serialización personalizada:
en este código, vemos cómo guardar algunos atributos no serializables mediante serialización de direcciones con serialización personalizada. Tenga en cuenta que debemos marcar los atributos no serializables como transitorios para evitar la excepción NotSerializableException.,
conclusión
en este tutorial rápido, hemos revisado la serialización de Java, discutido cosas importantes a tener en cuenta y hemos mostrado cómo hacer la serialización personalizada.