Registros en Java
⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.
r8vnhill/java-dibs
En lecciones anteriores aprendimos a modelar tipos producto en Kotlin utilizando data class
: estructuras concisas que agrupan múltiples valores bajo una misma entidad, con campos claramente nombrados, igualdad estructural y generación automática de comportamientos útiles como toString
, equals
y copy
.
Java —históricamente más detallado y ceremonioso— incorporó una alternativa moderna para expresar este mismo concepto: los record
. Introducidos como preview en Java 14 y estabilizados en Java 16, los record
permiten definir estructuras inmutables de manera concisa, con comportamiento generado automáticamente por el compilador.
En esta lección compararemos ambos enfoques. Veremos cómo un record
en Java cumple un rol similar al de una data class
en Kotlin, qué características comparten, y qué diferencias existen en cuanto a expresividad, flexibilidad y casos de uso. También discutiremos sus limitaciones al diseñar bibliotecas centradas en datos.
Nos enfocaremos tanto en lo que los une —inmutabilidad, igualdad estructural, transparencia semántica— como en lo que los distingue: desde la posibilidad de desestructurar o copiar con cambios, hasta el nivel de control y extensión que permite cada lenguaje.
🎵 Ejemplo: Registro de canción con record
A continuación presentamos un ejemplo completo del uso de record
en Java para modelar un tipo producto simple: una canción con título, compositor, año de lanzamiento y si fue un éxito en Billboard.
- Código esencial
- Código completo
public record Song(
String title,
String writer,
int releaseYear,
boolean billboardHit
) {}
package cl.ravenhill.music;
public record Song(
String title,
String writer,
int releaseYear,
boolean billboardHit
) {}
package cl.ravenhill.music;
public class Main {
public static void main(String[] args) {
var song = new Song(
"Walk On By",
"Burt Bacharach",
1964,
true
);
System.out.println(song);
System.out.println(song.billboardHit()
? song.title() + " was a Billboard hit!"
: song.title() + " didn't chart.");
}
}
Song[title=Walk On By, writer=Burt Bacharach, releaseYear=1964, billboardHit=true]
Walk On By was a Billboard hit!
Este ejemplo demuestra cómo Java permite modelar tipos producto inmutables de forma concisa usando record
, una característica introducida en Java 14 y estabilizada en Java 16.
- La clase
Song
actúa como una estructura de datos declarativa con campos nombrados, similar a unadata class
en Kotlin. - El compilador genera automáticamente:
- Un constructor compacto con todos los campos.
- Los métodos
toString
,equals
,hashCode
. - Y los métodos para acceder a cada campo (como
title()
owriter()
), sin necesidad de prefijos comogetTitle()
ogetWriter()
, lo cual hace que el código sea más limpio y legible que las clases tradicionales en Java.
Este estilo reduce el código repetitivo y comunica con claridad la intención: estamos definiendo una entidad que representa datos, no comportamiento.
Este enfoque se alinea con el concepto de registro como una unidad de datos inmutable, autoexpresiva y fácilmente comparable — tal como vimos con data class
en Kotlin.
🎯 Conclusiones
El soporte moderno de Java para record
permite expresar tipos producto de forma concisa y segura, acercando su modelo de datos al de lenguajes más declarativos como Kotlin. Aunque los record
no ofrecen todas las funcionalidades de una data class
—como copy()
o desestructuración mediante componentN()
—, sí representan un paso importante hacia la simplificación del diseño orientado a datos en Java.
Esta lección muestra cómo Java puede modelar estructuras inmutables y comparables por valor con una sintaxis clara, evitando la verbosidad de las clases tradicionales cuando el objetivo es simplemente representar datos.
🔑 Puntos clave
- Un
record
en Java define un tipo producto inmutable con semántica por valor. - El compilador genera automáticamente métodos como
equals
,hashCode
ytoString
. - Los campos son inmutables y accesibles mediante métodos sin prefijo (
title()
en lugar degetTitle()
). - Aunque conciso, un
record
no admite herencia ni operaciones como copia o desestructuración automática. - Es conceptualmente equivalente a una
data class
de Kotlin, pero con un conjunto de capacidades más acotado.
📊 Comparativa: Kotlin vs Java
Característica | Kotlin (data class ) | Java (record ) |
---|---|---|
Declaración | data class Person(...) | record Person(...) |
Comparación por valor (== ) | ✅ Generada automáticamente (equals ) | ✅ Generada automáticamente (equals ) |
Representación legible (toString ) | ✅ Generada automáticamente | ✅ Generada automáticamente |
Hashing (hashCode ) | ✅ Generado automáticamente | ✅ Generado automáticamente |
Desestructuración (componentN() ) | ✅ Sí (hasta 255 campos) | ❌ No |
Clonación (copy ) | ✅ Con copy(...) | ❌ No (debe escribirse manualmente) |
Inmutabilidad | ✅ Campos val (aunque puede usarse var ) | ✅ Campos inmutables por defecto |
Constructor con todos los campos | ✅ Sí | ✅ Sí |
Herencia | ❌ No | ❌ No (los record son implícitamente final ) |
🧰 ¿Qué nos llevamos?
Tanto record
como data class
son mecanismos diseñados para reducir la fricción al modelar datos. En ambos casos, su objetivo es permitirte declarar tipos producto con semántica fuerte, evitando la necesidad de generar manualmente código repetitivo para comparaciones, impresiones o acceso a campos.
Para quienes vienen de Java, entender record
es fundamental para adoptar prácticas más modernas y expresivas. Para quienes ya conocen Kotlin, esta comparación refuerza que los conceptos de la teoría de tipos —como los productos— se implementan de forma distinta en cada lenguaje, pero persiguen los mismos principios: claridad, seguridad y simplicidad.
Ambos mecanismos promueven la inmutabilidad, la transparencia semántica y el diseño modular, cualidades esenciales para construir bibliotecas reutilizables y mantenibles.
📖 Referencias
🔥 Recomendadas
- 🎥 "Complete Java Records Tutorial" (20m13s) en YouTube por Cameron McKenzie: Este video ofrece una introducción práctica y detallada a los
record
en Java, destacando su utilidad para modelar datos inmutables de forma concisa y segura. McKenzie contrasta el enfoque tradicional —basado en clases verbosas con getters,equals
,hashCode
ytoString
manuales— con la simplicidad declarativa de losrecord
, mostrando cómo esta característica reduce errores, mejora el rendimiento y facilita el mantenimiento del código. Además, aborda temas avanzados como constructores personalizados, validaciones internas, métodos estáticos y restricciones de herencia. Es especialmente relevante para esta lección porque refuerza la idea de que losrecord
son el equivalente idiomático de lasdata class
de Kotlin en el ecosistema Java, aportando claridad y eficiencia al modelado de tipos producto.
🔹 Adicionales
- 🌐 "JEP 395: Records" en OpenJDK: Propuesta oficial que introdujo los
record
en Java 16 como una forma concisa, inmutable y nominalmente tipada de modelar datos. Este documento explica la motivación detrás de losrecord
(reducir el código repetitivo al declarar tipos producto), su semántica, sus limitaciones (como la ausencia de desestructuración o clonación automática), y su integración con otras características modernas del lenguaje como las clasessealed
y la futura coincidencia de patrones (pattern matching). Es relevante para esta lección porque establece las bases formales y filosóficas de losrecord
como equivalente conceptual a lasdata class
de Kotlin: ambos permiten declarar estructuras orientadas a datos con semántica por valor, constructor canónico y métodos derivados automáticamente. También detalla las restricciones de diseño (inmutabilidad, final por defecto, sin herencia) que los hacen especialmente útiles en la construcción de bibliotecas reutilizables.