Java Language Serialización básica en Java


Ejemplo

¿Qué es la serialización?

La serialización es el proceso de convertir el estado de un objeto (incluidas sus referencias) en una secuencia de bytes, así como el proceso de reconstruir esos bytes en un objeto vivo en algún momento futuro. La serialización se utiliza cuando desea persistir el objeto. Java RMI también lo utiliza para pasar objetos entre JVM, ya sea como argumentos en una invocación de método de un cliente a un servidor o como valores de retorno de una invocación de método, o como excepciones lanzadas por métodos remotos. En general, la serialización se usa cuando queremos que el objeto exista más allá de la vida útil de la JVM.

java.io.Serializable es una interfaz de marcador (no tiene cuerpo). Solo se utiliza para "marcar" clases de Java como serializables.

El tiempo de ejecución de serialización asocia con cada clase serializable un número de versión, llamado serialVersionUID , que se usa durante la des- serialización para verificar que el remitente y el receptor de un objeto serializado hayan cargado clases para ese objeto que sean compatibles con respecto a la serialización. Si el receptor ha cargado una clase para el objeto que tiene un serialVersionUID diferente al de la clase del remitente correspondiente, la deserialización dará como resultado una InvalidClassException . Una clase serializable puede declarar su propio serialVersionUID declarando explícitamente un campo llamado serialVersionUID que debe ser static, final, y de tipo long :

ANY-ACCESS-MODIFIER static final long serialVersionUID = 1L;

Cómo hacer que una clase sea elegible para la serialización

Para conservar un objeto, la clase respectiva debe implementar la interfaz java.io.Serializable .

import java.io.Serializable;

public class SerialClass implements Serializable {

    private static final long serialVersionUID = 1L;  
    private Date currentTime;
    
    public SerialClass() {
        currentTime = Calendar.getInstance().getTime();
    }

    public Date getCurrentTime() {
        return currentTime;
    }
}

Cómo escribir un objeto en un archivo

Ahora necesitamos escribir este objeto en un sistema de archivos. Usamos java.io.ObjectOutputStream para este propósito.

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;

public class PersistSerialClass {

    public static void main(String [] args) {
        String filename = "time.ser";            
        SerialClass time = new SerialClass(); //We will write this object to file system.
        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
            out.writeObject(time); //Write byte stream to file system.
            out.close();
        } catch(IOException ex){
            ex.printStackTrace();
        }
     }
 }

Cómo recrear un objeto desde su estado serializado

El objeto almacenado puede leerse desde el sistema de archivos más tarde usando java.io.ObjectInputStream como se muestra a continuación:

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.java.lang.ClassNotFoundException;

 public class ReadSerialClass {

    public static void main(String [] args) {
        String filename = "time.ser";    
        SerialClass time = null;

        try {
            ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
            time = (SerialClass)in.readObject();
            in.close();
        } catch(IOException ex){
            ex.printStackTrace();
        } catch(ClassNotFoundException cnfe){
            cnfe.printStackTrace();
        }
        // print out restored time
        System.out.println("Restored time: " + time.getTime());
     }
 }

La clase serializada está en forma binaria. La deserialización puede ser problemática si la definición de la clase cambia: consulte el capítulo Control de versiones de objetos serializados de la Especificación de serialización de Java para obtener más detalles.

Serializar un objeto serializa el gráfico de objeto completo del cual es la raíz, y funciona correctamente en presencia de gráficos cíclicos. Se proporciona un método reset() para forzar que ObjectOutputStream olvide de los objetos que ya se han serializado.

Campos transitorios - Serialización