Trabajar con records en Java próximamente va a ser mejor

Java está trabajando para superar una de las limitaciones más notorias de los records en su lenguaje: la dificultad para crear registros derivados a partir de otros sin tener que reescribir todo el objeto. Esta mejora se está planteando en un nuevo JEP (Java Enhancement Proposal), que aunque todavía está en fase de borrador y sin número asignado, promete facilitar la manipulación de registros inmutables.

Los records en Java son una forma simplificada de definir clases que agrupan datos sin la necesidad de escribir getters, setters o constructores manualmente. Basta con declarar un record con sus atributos para tener una clase inmutable lista para usar. Esta inmutabilidad es especialmente útil en entornos concurrentes, ya que evita problemas derivados de la modificación simultánea de variables por múltiples hilos.

Sin embargo, esta característica también implica una limitación importante: no existen setters para modificar los campos de un record una vez creado. Si queremos cambiar un valor, debemos crear un nuevo record copiando todos los campos del original y modificando solo el que nos interesa. Esto puede volverse tedioso y propenso a errores, especialmente cuando los records tienen muchos atributos o cuando se requiere modificar campos con frecuencia.

Para ilustrar esta situación, imaginemos que tenemos un record User con tres campos: username, accessToken y refreshToken. Si queremos actualizar el accessToken, no podemos simplemente llamar a un setter. En su lugar, debemos crear un nuevo User copiando manualmente los valores antiguos y cambiando solo el token de acceso. Esto se complica aún más si añadimos más campos al record, ya que tendríamos que actualizar todos los métodos que crean copias modificadas.

Una práctica común para sortear esta limitación es implementar métodos llamados withers, que devuelven una copia del record con un campo modificado. Por ejemplo, un método withAccessToken(String newToken) que crea un nuevo User con el token actualizado. Aunque funcional, esta solución va en contra del espíritu de los records, que buscan reducir la cantidad de código repetitivo.

La propuesta que Java está considerando introduce una palabra clave with que actúa como un operador para crear registros derivados de forma sencilla y legible. La sintaxis permite tomar un record existente y, dentro de unas llaves, especificar solo los campos que queremos modificar. El resultado es una copia del record original con esos cambios aplicados, sin necesidad de escribir métodos adicionales ni copiar manualmente todos los campos.

Por ejemplo, si tenemos un record Point con campos x, y y z, podríamos escribir:

Point nextPoint = point with { x = 0 };

Esto crea una copia de point donde solo el valor de x cambia a 0, mientras que y y z mantienen sus valores originales. También es posible realizar operaciones más complejas dentro de las llaves, como multiplicar valores:

Point nextPoint = point with {
    x = x * 2,
    y = y * 2,
    z = z * 2
};

En este caso, cada coordenada se duplica en la nueva instancia.

Esta funcionalidad no solo simplifica la modificación de registros, sino que también facilita la implementación de operaciones matemáticas o transformaciones en tipos de datos inmutables. Por ejemplo, para un record Complex que representa números complejos con parte real e imaginaria, podemos definir métodos como conjugate que invierten la parte imaginaria sin afectar la parte real:

public Complex conjugate() {
    return this with { imaginary = -imaginary };
}

O métodos que devuelven solo la parte real o imaginaria, estableciendo la otra a cero:

public Complex realOnly() {
    return this with { imaginary = 0 };
}

public Complex imaginaryOnly() {
    return this with { real = 0 };
}

Aunque esta propuesta aún está en fase inicial y tardará en llegar a una versión estable de Java, representa un avance significativo para trabajar con records de manera más cómoda y expresiva, manteniendo la inmutabilidad y reduciendo la necesidad de código repetitivo.

Así, pronto podremos crear registros derivados con una sintaxis clara y concisa, mejorando la experiencia de desarrollo en Java y acercándonos a las facilidades que otros lenguajes modernos ya ofrecen para manejar datos inmutables.

Lista de reproducción
  1. 1
    Java 22 ya está aquí: novedades del JDK
    9 minutos
  2. 2
    Main implícito: Java va a arreglar la forma de escribir el main
    10 minutos
  3. 3
    Java por fin va a tener string interpolations
    10 minutos
  4. 4
    Trabajar con records en Java próximamente va a ser mejor
    9 minutos