Lombok getter/setter vs registro de Java 14

7 minutos de lectura

avatar de usuario
gixlg

amo el proyecto Lombok pero en estos dias estoy leyendo y probando algunas de las nuevas caracteristicas de java 14.

Dentro de la nueva capacidad, está la registro palabra clave que permite crear una clase con la siguiente funcionalidad ya incorporada: constructor, campos finales privados, métodos de acceso, equals/hashCode, getters, toString.

Ahora mi pregunta es: es mejor confiar en la función de Lombok o deberíamos comenzar a usar la función de registro:

Es mejor usar esto:

record Person (String name, String surname) {}

o eso:

@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Person {
  @Getter private int name;
  @Getter private int surname;
}

¿Cuáles son los pros y los contras de ambos enfoques?

  • Por una cosa, record no funcionará para las cosas que esperan getters y setters al estilo de JavaBeans.

    – Mark Rotteveel

    19 de abril de 2020 a las 15:23


  • Lo que significa el comentario de Rotteveel es que el método de acceso a la propiedad en un registro tiene el mismo nombre que la propiedad. Asi que, alice.phoneNumber() en lugar de la convención JavaBeans de prefijar con getcomo en alice.getPhoneNumber().

    – Basil Bourque

    19 de abril de 2020 a las 15:29

  • Los registros tienen muchas restricciones en comparación con las clases, por ejemplo, un registro no puede extender otro registro o clase, consulte la sección de restricciones en este JEP openjdk.java.net/jeps/359 para mas detalles

    – Youssef NAIT

    19 de abril de 2020 a las 15:36


  • Su muestra está muy sesgada hacia el registro. Cuando se escribe sin toda la grasa que agregó en la clase anterior, la diferencia es mucho menor: record Person (String name, String surname) {} contra: @Value class Person { int name; int surname; } Más otros, solo cambia @Value a @Data y mágicamente tendrás una clase no inmutable compatible con ORM. Algo que no es posible o difícil de lograr con java 17 record.

    – Zartc

    17 de febrero a las 14:54


avatar de usuario
Brian Goetz

Lombok, y el record característica del lenguaje Java, son diferentes herramientas para diferentes cosas. Hay cierta superposición superficial, pero no dejes que eso te distraiga.

Lombok se trata en gran parte de sintáctico conveniencia; es un macroprocesador precargado con algunos patrones de código útiles conocidos. No confiere ninguna semántica; simplemente automatiza los patrones, de acuerdo con algunas perillas que configuraste en el código con anotaciones. Lombok se trata únicamente de la conveniencia de implementar clases de transporte de datos.

Los registros son un semántico rasgo; están tuplas nominales. Al hacer una declaración semántica de que Point es una tupla de (int x, int y), el compilador puede derivar su representación, así como los protocolos de construcción, declaración, igualdad, hashing y representación de cadenas, a partir de esta descripción de estado. Debido a que llevan semántica, los lectores y los marcos también pueden razonar con mayor confianza sobre la API de los registros. (Esto también puede ser sintácticamente conveniente; si es así, genial).

  • +1 Brian Goetz: Y eso suponiendo que pueda obtener la versión actual de Lombok en su IDE. Me pregunto si Lombok tiene alguna ventaja significativa con respecto a una lectura de código más rápida que un comentario de clase no conferiría.

    – Tronco

    25 de abril de 2020 a las 18:29

  • Sostengo que no son tuplas del todo nombradas: las tuplas generales no requieren ninguna definición. Pero los tipos de registro aún deben definirse antes del uso. En C#, esto se puede hacer: (cadena primero, cadena en medio, cadena al final) methodThatReturnsATuple()

    – Solubris

    11/06/2020 a las 11:30

  • @Solubris Si puede definir “tupla”, entonces, por supuesto, tiene razón. Tuvimos este mismo debate sobre si Java 8 lambdas eran cierres “reales”; esto siempre se reducía, en algún nivel, a “Creo que ‘cierre’ significa X porque eso es lo que significaba en el primer idioma en el que lo encontré”. Pero no es un debate muy productivo.

    – Brian Goetz

    11 de junio de 2020 a las 16:51

  • Existen numerosas diferencias en lo que sería una definición sensata de una tupla, por lo que creo que es engañoso asociar tipos de registro con tuplas de todos modos. Por ejemplo: record Point(int x, int y) { } record Offset(int x, int y) { } var p1 = new Point(1, 2); var o1 = nuevo Desplazamiento (1, 2); System.out.println(p1.equals(o1)); Esto imprime falso, pero esto no tiene sentido para las tuplas.

    – Solubris

    11 de junio de 2020 a las 21:26

  • Creo que podría haber sido útil incluir un descargo de responsabilidad como el que hizo rzwitserloot antes que usted, indicando que usted era el autor de Records (openjdk.java.net/jeps/384). Puede estar sesgado en cuanto a su flexibilidad y utilidad en comparación con @Value.

    – usuario3742898

    4 de marzo de 2021 a las 16:06

NB: en lugar de ese árbol de navidad de anotaciones, puedes usar @Value en la clase Tenga en cuenta que esto hace que la clase sea final, y hace que todos los campos sean privados y finales, y también le da todo el resto. Esto se acerca a lo que son los registros (ellos también son definitivos, y todos los campos internos son definitivos).

record todavía está en vista previa, por lo que para el código de producción, obviamente, aún no es adecuado. Usa lombok.

Una vez que los registros están fuera de la vista previa, es más complicado. Lombok es LEJOS mas flexible; puede intercambiar fácilmente algún aspecto nuevo sin tener que volver a escribir todo el código (puede, por ejemplo, agregar una cláusula ‘extiende’ a su clase sin tener que escribir a mano el método equals y hashCode; algo que los registros no pueden darle). Lombok también le brinda más funciones: puede, por ejemplo, agregar un constructor agregando el @Builder anotación; no es algo que los registros puedan hacer.

Si es muy poco probable que vaya a usar algo de eso para la clase que está diseñando, usaría registros.

DESCARGO DE RESPONSABILIDAD: Soy un colaborador principal del Proyecto Lombok.

avatar de usuario
Namán

También he estado jugando con esta combinación durante algún tiempo y con un poco de práctica podría enumerar las siguientes diferencias:

Lombok

  • Los registros aún no son una herramienta tan poderosa para eliminar a Lombok por completo. Tenga en cuenta que la biblioteca tiene mucho más que ofrecer que solo la @Getter, @AllArgsConstructor, @ToString, @EqualsAndHashCode.
  • Experimentado por uno mismo, el EqualsAndHashCode no es lo mismo que cabría esperar cuando se trata de migrar a registros.

Registros

  • Los registros son una parte oficial del lenguaje, con el apoyo de todos los principales IDE
  • En una nota diferente, si el requisito de la representación de su objeto es ser un “portador de datos”, aún puede buscar la ventaja de los Registros, sin depender de una biblioteca adicional para reducir el código repetitivo para realizar eso con precisión. Esa es la razón por la que como nota conclusiva este blog lee lo siguiente:

También ayudará a los equipos a eliminar muchas implementaciones codificadas a mano del patrón subyacente y reducir o eliminar la necesidad de bibliotecas como Lombok.

Por supuesto, en el día a día, siempre es prudente, según los requisitos de un proyecto, elegir qué camino seguir y practicar.

  • Nota: trataría de mantener esto actualizado con más ejemplos por ser un usuario que usa ambos con frecuencia en la actualidad.

    – Namán

    19 de abril de 2020 a las 16:11


avatar de usuario
Stefan Feuerhahn

Si bien Brian explica bien los diferentes objetivos de Lombok y los registros, no explica cuándo usar cuál.

Si tu clase es una “agregado de datos transparente, superficialmente inmutable” entonces un registro hará un gran trabajo porque:

  1. tiene incluso menos ceremonia que una clase anotada con Lombok
  2. lleva la información semántica “esta es una clase de datos inmutable” (como se enfatiza en la respuesta de Brian Goetz). Esta información semántica puede ser valiosa tanto para programadores como para frameworks.

Todavía usaría Lombok si su clase no puede vivir con las restricciones de los registros (por ejemplo, inmutabilidad, sin constructor, no extensible).

avatar de usuario
Laura Liparulo

Java Records no requiere ninguna dependencia adicional, por lo que creo que es mejor usarlos en lugar de Lombok.

Si su proyecto es compatible con Java 14, ya puede usarlos en Eclipse.

Hay un complemento en el mercado para ello:

https://marketplace.eclipse.org/content/java-14-support-eclipse-2020-03-415

avatar de usuario
usuario17570798

En resumen, si está haciendo codificación funcional con Java, use registros. De lo contrario, use Lombok, es mucho más flexible y potente.

Hay algunas excepciones a esta regla, por ejemplo, en la codificación API.

¿Ha sido útil esta solución?