6.3 Serialización

Java facilita el almacenamiento y transmisión del estado de un objeto mediante un mecanismo conocido con el nombre de serialización.

La serialización de un objeto consiste en generar una secuencia de bytes lista para su almacenamiento o transmisión. Después, mediante la deserialización, el estado original del objeto se puede reconstruir.

Para que un objeto sea serializable, ha de implementar la interfaz java.io.Serializable (que lo único que hace es marcar el objeto como serializable, sin que tengamos que implementar ningún método).

import java.io.*;

public class Persona implements Serializable {

    private String nombre;
    transient private int edad; //No se guardará al serializar
    private double salario;
    private Persona tutor;
    [...]
}
  • Para que un objeto sea serializable, todas sus variables de instancia han de ser serializables.

  • Todos los tipos primitivos en Java son serializables por defecto (igual que los arrays y otros muchos tipos estándar).

  • Cuando queremos evitar que cualquier campo persista en un archivo, lo marcamos como transitorio (transient). No podemos marcar ningún método transitorio, solo campos.

  • Para leer o escribir de/en un fichero binario que incluye información seriarizable se utilizará los streams ObjectInpuStream y ObjectOutputStream con los métodos readObject() y writeObject(ClaseSerializada obj) respectivamente.

El fichero con los objetos serializados almacena los datos en un formato propio de Java, por lo que no se puede leer fácilmente con un simple editor de texto (ni editar).

Ejemplo: serialización

package UT06.P3_Serializacion;

import java.io.*;

public class Persona implements Serializable {

  private String nombre;
  transient private int edad; //No se guardará al serializar
  private double salario;
  private Persona tutor;

  public Persona(String nom, double salari) {
     this.nombre = nom;
     this.salario = salari;
     edad = 0;
     tutor = null;
  }

  public String getNombre() {
     return nombre;
  }

  public int getEdad() {
     return edad;
  }

  public double getSalario() {
     return salario;
  }

  public Persona getTutor() {
     return tutor;
  }

  public void incrementaEdad() {
     edad++;
  }

  public void asignaTutor(Persona p) {
     tutor = p;
  }
}
Ahora detallamos la clase para serializar o guardar la información en un archivo mediante el stream ObjectOutputStream:
package UT06.P3_Serializacion;

import java.io.*;

public class Guardar {

  public static void main(String args[]) {
     ObjectOutputStream salida;
     Persona p1, p2, p3, p4;

     p1 = new Persona("Vicent", 1200.0);
     p2 = new Persona("Mireia", 1800.0);
     p3 = new Persona("Josep", 2100.0);
     p4 = new Persona("Marta", 850.0);

     p1.asignaTutor(p2);
     p2.asignaTutor(p3);
     p3.asignaTutor(p4);

     try {
        salida = new ObjectOutputStream(new FileOutputStream("empleados.ser"));
        salida.writeObject(p1);
        salida.close();

     } catch (IOException e) {
        System.out.println("ERROR: Algún problema guardando a disco.");
     }
  }
}
Como la clase Persona implementa Serializable significa que p1 y todos los objetos referenciados por él (como p2, p3, p4) serán serializados en cadena.