En este artículo te muestro, paso a paso, cómo modelar una Persona con nombre
, apellido
y DNI (con validación española), cómo almacenar varias personas en un ArrayList, serializar esa lista y guardarla en un archivo binario. Además, veremos cómo leer el archivo para recuperar los objetos.
Requisitos
- JDK 17 o superior (vale desde 8, pero recomiendo 17+).
- Cualquier IDE (IntelliJ / Eclipse / NetBeans) o la terminal.
- Conocimientos básicos de Java y colecciones.
¿Qué es “serializar” en Java?
Serializar es convertir un objeto a una secuencia de bytes para poder guardarlo (por ejemplo, en un archivo) o enviarlo por red. En Java se hace implementando la interfaz Serializable
y usando ObjectOutputStream
/ ObjectInputStream
.
Estructura del proyecto
src/
├─ Persona.java
└─ Main.java
Clase Persona
(con validación de DNI)
- Campos:
nombre
,apellido
,dni
. - Implementa
Serializable
. - Valida el DNI español (8 dígitos + letra correcta).
Nota: El algoritmo de la letra del DNI usa la cadena
"TRWAGMYFPDXBNJZSQVHLCKE"
.
Letra =letras[numero % 23]
.
// Persona.java
import java.io.Serializable;
public class Persona implements Serializable {
private static final long serialVersionUID = 1L;
private final String nombre;
private final String apellido;
private final String dni; // Formato: 8 dígitos + letra correcta (ej: 12345678Z)
public Persona(String nombre, String apellido, String dni) {
if (nombre == null || nombre.isBlank()) {
throw new IllegalArgumentException("El nombre no puede estar vacío.");
}
if (apellido == null || apellido.isBlank()) {
throw new IllegalArgumentException("El apellido no puede estar vacío.");
}
String normalizado = (dni == null) ? "" : dni.trim().toUpperCase();
if (!isDniValido(normalizado)) {
throw new IllegalArgumentException("DNI inválido: " + dni);
}
this.nombre = nombre.trim();
this.apellido = apellido.trim();
this.dni = normalizado;
}
public String getNombre() { return nombre; }
public String getApellido() { return apellido; }
public String getDni() { return dni; }
@Override
public String toString() {
return nombre + " " + apellido + " (" + dni + ")";
}
// ====== Validación DNI ======
public static boolean isDniValido(String dni) {
if (dni == null) return false;
dni = dni.trim().toUpperCase();
if (!dni.matches("\\d{8}[A-Z]")) return false;
String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
int numero = Integer.parseInt(dni.substring(0, 8));
char letraEsperada = letras.charAt(numero % 23);
return dni.charAt(8) == letraEsperada;
}
}
Programa principal: crear ArrayList<Persona>
, serializar y deserializar
- Creamos algunas personas de ejemplo.
- Guardamos el
ArrayList
enpersonas.bin
. - Leemos el archivo y listamos por consola.
// Main.java
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class Main {
private static final String RUTA_ARCHIVO = "personas.bin";
public static void main(String[] args) {
// 1) Crear la lista de personas
List<Persona> personas = new ArrayList<>();
personas.add(new Persona("Ana", "López", "12345678Z")); // Válido
personas.add(new Persona("Carlos", "Pérez", "11111111H")); // Válido
personas.add(new Persona("Lucía", "Martín", "87654321X")); // Válido
// 2) Serializar y guardar en archivo binario
guardarPersonas(personas, RUTA_ARCHIVO);
// 3) Leer de archivo (deserializar) y mostrar
List<Persona> leidas = leerPersonas(RUTA_ARCHIVO);
System.out.println("Personas leídas desde el archivo:");
if (leidas != null) {
for (Persona p : leidas) {
System.out.println(" - " + p);
}
}
}
// ====== Serialización ======
private static void guardarPersonas(List<Persona> personas, String ruta) {
try (ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(new FileOutputStream(ruta)))) {
oos.writeObject(personas);
System.out.println("✅ Guardadas " + personas.size() + " personas en: " + ruta);
} catch (IOException e) {
System.err.println("❌ Error al guardar personas: " + e.getMessage());
e.printStackTrace();
}
}
// ====== Deserialización ======
@SuppressWarnings("unchecked")
private static List<Persona> leerPersonas(String ruta) {
try (ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(new FileInputStream(ruta)))) {
Object obj = ois.readObject();
if (obj instanceof List<?>) {
return (List<Persona>) obj;
} else {
System.err.println("❌ El archivo no contiene una List<Persona>.");
}
} catch (FileNotFoundException e) {
System.err.println("❌ Archivo no encontrado: " + ruta);
} catch (IOException | ClassNotFoundException e) {
System.err.println("❌ Error al leer personas: " + e.getMessage());
e.printStackTrace();
}
return null;
}
}
Ejecución desde la terminal
Dentro del directorio src
(o ajusta rutas según tu IDE):
javac Persona.java Main.java
java Main
Verás algo como:
✅ Guardadas 3 personas en: personas.bin
Personas leídas desde el archivo:
- Ana López (12345678Z)
- Carlos Pérez (11111111H)
- Lucía Martín (87654321X)
Se crea el archivo personas.bin
en el directorio actual.
Añadiendo personas por consola (opcional)
Si prefieres pedir datos al usuario, puedes usar Scanner
y luego llamar a guardarPersonas(...)
.
Consejo: siempre valida el DNI antes de crear la Persona
.
// Fragmento opcional para leer por consola
/*
Scanner sc = new Scanner(System.in);
System.out.print("Nombre: ");
String nombre = sc.nextLine();
System.out.print("Apellido: ");
String apellido = sc.nextLine();
System.out.print("DNI (8 dígitos + letra): ");
String dni = sc.nextLine();
if (!Persona.isDniValido(dni)) {
System.out.println("DNI inválido.");
} else {
personas.add(new Persona(nombre, apellido, dni));
guardarPersonas(personas, RUTA_ARCHIVO);
}
*/
Errores comunes y cómo resolverlos
java.io.NotSerializableException
Alguna clase en tu grafo de objetos no implementaSerializable
. Asegúrate de que Persona (y cualquier otra clase interna) lo implemente.InvalidClassException
tras cambios en la clase
Cambiar la estructura de la clase después de haber serializado puede romper la lectura. Define unserialVersionUID
fijo para mayor control.ClassCastException
al leer
Verifica que el archivo contiene exactamente unaList<Persona>
(y no otra cosa).
Copiar/pegar en WordPress
- En el editor de bloques (Gutenberg), inserta un bloque Código y pega los fragmentos con el idioma Java para resaltar sintaxis.
- Estructura el post con
H2/H3
, tal como en este artículo, para buen SEO y legibilidad.
Resumen
- Modelamos
Persona
con validación de DNI. - Usamos
ArrayList<Persona>
para almacenar varias personas. - Serializamos con
ObjectOutputStream
apersonas.bin
. - Deserializamos con
ObjectInputStream
para recuperar la lista.
Contenido restringido
Comments are closed