Desde Java 14, el lenguaje incorporó una nueva forma de definir clases de datos: los records.
Su objetivo es simple: reducir el boilerplate cuando solo queremos representar datos inmutables.
¿Qué problema vienen a resolver?
Antes de records, una clase típica para representar datos se veía así:
public class Persona {
private final String nombre;
private final int edad;
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public int getEdad() {
return edad;
}
@Override
public boolean equals(Object o) { ... }
@Override
public int hashCode() { ... }
@Override
public String toString() { ... }
}
Mucho código repetitivo, ¿no?
Con records, lo mismo se define así:
public record Persona(String nombre, int edad) {}
Y listo.
Java automáticamente genera:
- Constructor
- Getters (sin prefijo get)
- equals()
- hashCode()
- toString()
Un record es una clase especial que:
- Es inmutable
- Es final
- Extiende implícitamente de java.lang.Record
Persona p = new Persona("Juan", 30);
System.out.println(p.nombre()); // Juan
System.out.println(p.edad()); // 30
Podemos hacer un constructor personalizado por ejemplo para validar datos:
public record Persona(String nombre, int edad) {
public Persona {
if (edad < 0) {
throw new IllegalArgumentException("Edad inválida");
}
}
}
Este es un constructor compacto.
Los records no son solo datos, también pueden tener lógica:
public record Persona(String nombre, int edad) {
public boolean esMayorDeEdad() {
return edad >= 18;
}
}
Restricciones importantes:
- No podés extender otras clases
- Los atributos son implícitamente final
- No hay setters
- No están pensados para entidades mutables (ej: JPA)
¿Cuándo usar Records?
Usalos cuando:
✔ Tenés objetos de solo datos (DTOs)
✔ Querés inmutabilidad
✔ Buscás claridad y menos boilerplate
Evitarlos cuando:
❌ Necesitás mutabilidad
❌ Estás modelando entidades complejas
❌ Usás frameworks que requieren setters (como JPA tradicional)
Con features modernas (Java 21+), los records se integran muy bien con pattern matching:
if (obj instanceof Persona(String nombre, int edad)) {
System.out.println(nombre);
}
Esto hace el código más declarativo y expresivo.
Los records son una de las mejoras más importantes en Java moderno:
- Reducen código repetitivo
- Fomentan inmutabilidad
- Mejoran la legibilidad
Son ideales para modelar datos de forma clara y segura.
.jpeg)