🚀 Serialización de Objetos en Java¶
La serialización en Java permite convertir objetos en una secuencia de bytes para que puedan ser almacenados en archivos, enviados por red o guardados en bases de datos. Luego, esos bytes pueden ser desserializados para reconstruir el objeto original.
¿Por qué es Importante la Serialización?¶
📌 Permite guardar objetos en archivos o bases de datos para su posterior uso.
📌 Facilita la comunicación en red (envío de objetos entre sistemas).
📌 Es clave en tecnologías como RMI (Remote Method Invocation), donde se envían objetos entre JVMs.
📌 Ayuda en la caché y persistencia de datos en aplicaciones grandes.
Cómo Serializar y Deserializar en Java¶
Para que un objeto sea serializable, su clase debe implementar la interfaz Serializable.
📌 Ejemplo Básico de Serialización¶
import java.io.*;
// Implementamos Serializable
class Persona implements Serializable {
private static final long serialVersionUID = 1L; // ID de versión para compatibilidad
private String nombre;
private int edad;
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
@Override
public String toString() {
return "Persona{nombre='" + nombre + "', edad=" + edad + "}";
}
}
public class SerializacionEjemplo {
public static void main(String[] args) {
Persona persona = new Persona("Kevin", 25);
// Serializar objeto
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("persona.ser"))) {
oos.writeObject(persona);
System.out.println("Objeto serializado con éxito.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
✅ ¿Qué hicimos aquí?
1️⃣ Creamos la clase Persona e implementamos Serializable.
2️⃣ Guardamos el objeto en un archivo (persona.ser).
📌 Ejemplo de Deserialización¶
Ahora, recuperamos el objeto serializado.
import java.io.*;
public class DeserializacionEjemplo {
public static void main(String[] args) {
// Deserializar objeto
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("persona.ser"))) {
Persona persona = (Persona) ois.readObject();
System.out.println("Objeto deserializado: " + persona);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
✅ ¿Qué sucede aquí?
1️⃣ Leemos los bytes desde el archivo persona.ser.
2️⃣ Los reconstruimos como un objeto Persona.
3️⃣ Imprimimos el objeto en la consola.
Conceptos Claves en Serialización¶
📌 1️⃣ serialVersionUID¶
Es un identificador único para una clase serializable.
private static final long serialVersionUID = 1L;
🔹 Si cambias la estructura de la clase y no actualizas serialVersionUID, la deserialización fallará.
📌 2️⃣ Campos transient (Exclusión de Serialización)¶
Si hay datos que no quieres serializar, usa transient.
class Persona implements Serializable {
private static final long serialVersionUID = 1L;
private String nombre;
private transient int edad; // No se serializará
}
🔹 Al deserializar, edad tomará su valor por defecto (0 para int).
Serialización Personalizada con Externalizable¶
Si queremos mayor control sobre el proceso de serialización/deserialización, usamos Externalizable.
📌 Ejemplo de Externalizable¶
import java.io.*;
class Persona implements Externalizable {
private String nombre;
private int edad;
public Persona() { } // Necesario para Externalizable
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(nombre);
out.writeInt(edad);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
nombre = in.readUTF();
edad = in.readInt();
}
@Override
public String toString() {
return "Persona{nombre='" + nombre + "', edad=" + edad + "}";
}
}
✅ Ventajas de Externalizable
✔️ Mayor control sobre qué datos se serializan y cómo.
✔️ Puede comprimir datos antes de guardarlos.
Serialización en JSON con Jackson o Gson¶
Para aplicaciones modernas, es común usar JSON en lugar de Serializable.
📌 Ejemplo con Gson¶
import com.google.gson.Gson;
class Persona {
private String nombre;
private int edad;
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
}
public class GsonEjemplo {
public static void main(String[] args) {
Gson gson = new Gson();
Persona persona = new Persona("Kevin", 25);
// Convertir a JSON
String json = gson.toJson(persona);
System.out.println("JSON: " + json);
// Convertir de JSON a Objeto
Persona nuevaPersona = gson.fromJson(json, Persona.class);
System.out.println("Objeto deserializado: " + nuevaPersona);
}
}
✅ Ventajas de JSON
✔️ Más portable y legible que Serializable.
✔️ Compatible con APIs REST y bases de datos NoSQL.
🎯 Conclusión¶
📌 Usa Serializable cuando necesites guardar o transmitir objetos en un sistema Java puro.
📌 Usa Externalizable si necesitas control total sobre la serialización.
📌 Usa JSON (Gson, Jackson) si interactúas con APIs REST o bases de datos NoSQL.
Serialización en redes o bases de datos¶
🚀 Serialización en Redes y Bases de Datos en Java¶
Ahora que ya comprendemos la serialización de objetos en Java, vamos a ver cómo aplicarla en redes y bases de datos. Esto es clave para la comunicación entre sistemas y el almacenamiento eficiente de objetos.
1. Serialización en Redes (Sockets)¶
La serialización permite enviar objetos entre clientes y servidores a través de sockets. Esto es útil para aplicaciones de mensajería, juegos en red, APIs distribuidas, etc.
🔥 Ejemplo: Cliente-Servidor con Objetos Serializados¶
Vamos a construir una aplicación donde un cliente envía un objeto al servidor, y este lo recibe y lo imprime.
📌 1️⃣ Definir la Clase Serializable¶
import java.io.Serializable;
class Persona implements Serializable {
private static final long serialVersionUID = 1L;
private String nombre;
private int edad;
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
@Override
public String toString() {
return "Persona{nombre='" + nombre + "', edad=" + edad + "}";
}
}
📌 2️⃣ Servidor que Recibe el Objeto¶
El servidor escucha conexiones y deserializa el objeto recibido.
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Servidor {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(5000)) {
System.out.println("Servidor esperando conexiones...");
Socket socket = serverSocket.accept();
System.out.println("Cliente conectado.");
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Persona persona = (Persona) ois.readObject();
System.out.println("Objeto recibido: " + persona);
ois.close();
socket.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
📌 3️⃣ Cliente que Envía el Objeto¶
El cliente crea un objeto Persona y lo envía al servidor.
import java.io.*;
import java.net.Socket;
public class Cliente {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 5000);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
Persona persona = new Persona("Kevin", 25);
oos.writeObject(persona);
System.out.println("Objeto enviado al servidor.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
✅ Explicación
1️⃣ El servidor espera una conexión y lee el objeto serializado.
2️⃣ El cliente crea un objeto Persona y lo envía al servidor.
3️⃣ El servidor deserializa y muestra la información.
🔹 Este método se usa en sistemas distribuidos y microservicios en Java.
2. Serialización en Bases de Datos¶
En ocasiones, en lugar de almacenar los datos de un objeto en múltiples columnas, podemos serializarlo y guardarlo en una columna tipo BLOB (Binary Large Object).
🔥 Ejemplo: Guardar un Objeto en MySQL¶
📌 1️⃣ Crear la Base de Datos¶
CREATE TABLE personas (
id INT AUTO_INCREMENT PRIMARY KEY,
datos LONGBLOB
);
📌 2️⃣ Serializar y Guardar en MySQL¶
import java.io.*;
import java.sql.*;
public class SerializacionBD {
public static void main(String[] args) {
Persona persona = new Persona("Kevin", 25);
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");
PreparedStatement ps = conn.prepareStatement("INSERT INTO personas (datos) VALUES (?)")) {
// Serializar objeto
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(persona);
oos.close();
byte[] personaBytes = bos.toByteArray();
ps.setBytes(1, personaBytes);
ps.executeUpdate();
System.out.println("Objeto almacenado en la base de datos.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
✅ ¿Qué hace este código?
1️⃣ Convierte el objeto en bytes con ObjectOutputStream.
2️⃣ Guarda los bytes en la base de datos en una columna BLOB.
📌 3️⃣ Leer y Deserializar desde MySQL¶
import java.io.*;
import java.sql.*;
public class DeserializacionBD {
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT datos FROM personas WHERE id=1")) {
if (rs.next()) {
byte[] personaBytes = rs.getBytes("datos");
ByteArrayInputStream bis = new ByteArrayInputStream(personaBytes);
ObjectInputStream ois = new ObjectInputStream(bis);
Persona persona = (Persona) ois.readObject();
ois.close();
System.out.println("Objeto recuperado de la base de datos: " + persona);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
✅ ¿Qué hacemos aquí?
1️⃣ Leemos los bytes de la BD.
2️⃣ Los deserializamos para obtener el objeto original.
🔥 Comparación: Serialización con BLOB vs JSON¶
| Método | Ventajas | Desventajas |
|---|---|---|
| BLOB (Serializable) | ✅ Guarda el objeto completo. ✅ Ideal para objetos complejos. | ❌ No es legible por humanos. ❌ Solo se puede leer en Java. |
| JSON (Gson/Jackson) | ✅ Fácil de leer. ✅ Compatible con otras tecnologías. | ❌ No almacena comportamiento del objeto. |
[!IMPORTANT] > 📌 Si necesitas interoperabilidad con otros lenguajes (Python, JavaScript, etc.), usa JSON.
🎯 Conclusión¶
🔹 Serialización en redes permite enviar objetos entre cliente-servidor usando sockets.
🔹 Serialización en bases de datos permite almacenar objetos en BLOB o convertirlos a JSON.
🔹 Para APIs modernas, usar JSON es más eficiente y portable.