Records frente a clases y Lombok
Compare los records con las clases tradicionales y las anotaciones de Lombok para elegir la herramienta adecuada.
Records frente a clases y Lombok es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
Records frente a clases y Lombok
Java ofrece varios enfoques para crear tipos portadores de datos: clases normales con código repetitivo, Records (Java 16+) o anotaciones de Lombok. La elección adecuada depende del caso de uso.
El problema del código repetitivo
Una clase Java normal que actúe como portadora de datos simples requiere mucho código repetitivo: constructor, getters, equals, hashCode y toString, todo ello para apenas unos pocos campos.
// Traditional class — lots of boilerplate
class ProductOld {
private final String id;
private final String name;
private final double price;
public ProductOld(String id, String name, double price) {
this.id = id; this.name = name; this.price = price;
}
public String getId() { return id; }
public String getName() { return name; }
public double getPrice() { return price; }
@Override public boolean equals(Object o) { /* ... */ }
@Override public int hashCode() { /* ... */ }
@Override public String toString() { /* ... */ }
}La solución de los records
Un Record condensa la misma clase en una sola línea. El compilador genera automáticamente todo el código repetitivo.
// Record — one line, same functionality
record Product(String id, String name, double price) {}
// Usage is almost identical except accessors use component names (no get prefix)
Product p = new Product("P001", "Laptop", 999.99);
System.out.println(p.id()); // P001 (not getId())
System.out.println(p.name()); // Laptop
System.out.println(p.price()); // 999.99
System.out.println(p); // Product[id=P001, name=Laptop, price=999.99]Lombok @Data y @Value
Lombok genera código repetitivo durante la compilación mediante anotaciones. @Value crea una clase inmutable similar a los records; @Data crea una clase mutable.
// Lombok @Value — immutable (closest to record)
import lombok.Value;
@Value
public class LombokProduct {
String id;
String name;
double price;
// Lombok generates: all-args constructor, getters, equals, hashCode, toString
// Note: accessors follow getX() naming convention (getPrice(), not price())
}
// Lombok @Data — mutable
import lombok.Data;
@Data
public class MutableProduct {
private String id;
private String name;
private double price;
// Generates: getters, setters, equals, hashCode, toString, no-args constructor
}Diferencias clave
Diferencias importantes entre los records, Lombok @Value y las clases convencionales:
- Nombre de los accesores: los records usan
name(); Lombok usagetName() - Variante mutable: los records siempre son inmutables; Lombok ofrece @Data para la mutabilidad
- Herencia: los records no pueden extender clases; las clases de Lombok sí pueden
- Dependencia de la herramienta de compilación: Lombok requiere configurar un procesador de anotaciones; los records están integrados
Cuándo usar records
Los records son ideales cuando:
- El tipo es principalmente un contenedor de datos transparente (DTO, Value Object)
- La inmutabilidad forma parte del diseño deseado
- Está utilizando Java 16 o posterior y quiere evitar dependencias
- El tipo participa en pattern matching (sealed + records)
// Perfect record use cases:
record Coordinates(double lat, double lon) {}
record JwtClaims(String subject, String role, long expiresAt) {}
record PageRequest(int page, int size, String sortBy) {}
record ErrorResponse(int code, String message, String path) {}
// These are all simple data carriers with no mutable stateCuándo usar Lombok
Se prefiere Lombok cuando:
- Necesita beans mutables (por ejemplo, entidades JPA o clases de configuración de Spring)
- Los nombres de los accesores deben seguir la convención JavaBeans (
getX) para ser compatibles con los frameworks - Necesita
@Builderpara construir objetos complejos - Se necesita mutabilidad parcial (
@NonFinalen algunos campos)
// Lombok @Builder — great for complex object construction
import lombok.*;
@Builder
@Value
public class EmailMessage {
String to;
String from;
String subject;
String body;
List<String> attachments;
}
EmailMessage msg = EmailMessage.builder()
.to("user@example.com")
.from("noreply@app.com")
.subject("Welcome!")
.body("Thank you for signing up")
.attachments(List.of())
.build();Cuándo usar clases convencionales
Las clases convencionales siguen siendo apropiadas cuando:
- La clase tiene un comportamiento complejo que va más allá de transportar datos simples
- Necesita extender otra clase
- Se necesita un control detallado sobre hashCode/equals
- Se requiere un estado mutable con encapsulamiento
// Plain class — when behavior dominates over data
class ShoppingCart {
private final List<CartItem> items = new ArrayList<>();
private final String customerId;
public ShoppingCart(String customerId) {
this.customerId = customerId;
}
public void addItem(CartItem item) { items.add(item); }
public void removeItem(String sku) { items.removeIf(i -> i.sku().equals(sku)); }
public double total() { return items.stream().mapToDouble(CartItem::lineTotal).sum(); }
public boolean isEmpty() { return items.isEmpty(); }
}Combinar records y clases
Los records y las clases funcionan perfectamente juntos. Use records para los datos inmutables dentro de clases que administran un estado mutable.
// Record for the immutable event data
record UserEvent(String userId, String action, java.time.Instant timestamp) {
public static UserEvent now(String userId, String action) {
return new UserEvent(userId, action, java.time.Instant.now());
}
}
// Class for the mutable event store
class EventLog {
private final List<UserEvent> events = new ArrayList<>();
public void record(String userId, String action) {
events.add(UserEvent.now(userId, action));
}
public List<UserEvent> eventsFor(String userId) {
return events.stream()
.filter(e -> e.userId().equals(userId)).toList();
}
}Records en Spring Boot
Los records se integran bien con Spring Boot como cuerpos de solicitud y respuesta. El mapeador Jackson de Spring los gestiona con una configuración mínima.
// Spring Boot REST controller using records
import org.springframework.web.bind.annotation.*;
record CreateProductRequest(String name, double price, String category) {}
record ProductResponse(long id, String name, double price, String category) {}
@RestController
@RequestMapping("/api/products")
class ProductController {
@PostMapping
public ProductResponse create(@RequestBody CreateProductRequest req) {
// Jackson automatically deserializes JSON into the record
long id = productService.save(req);
return new ProductResponse(id, req.name(), req.price(), req.category());
}
}Comparación de rendimiento
Los tres enfoques producen esencialmente el mismo bytecode para contenedores de datos simples. El rendimiento es idéntico; la elección depende de la experiencia del desarrollador y de los requisitos.
// All three compile to approximately equivalent bytecode:
// - Records: compiler-generated, always immutable
// - Lombok @Value: annotation-processor-generated, always immutable
// - Plain class: hand-written
// The key runtime difference:
// Records: accessor is a method matching field name (price() not getPrice())
// Lombok/Class: accessor follows JavaBeans (getPrice())
// Jackson compatibility:
// Records: work natively in Jackson 2.12+ with no config
// Lombok: work with @JsonProperty or jackson-databind-lombok moduleComprobación rápida
¿Qué convención de nombres siguen los accesores de los records?
Resumen: records, clases y Lombok
Conclusiones principales:
- Los records generan automáticamente el constructor, los accesores (sin el prefijo get), equals, hashCode y toString
- Los records siempre son inmutables; use clases convencionales para el estado mutable
- Lombok @Value se aproxima a los records, pero usa nombres con getX() y requiere configuración
- Lombok @Builder destaca en la construcción de objetos complejos con muchos campos opcionales
- Los records son ideales para DTO, objetos de valor y cuerpos de solicitud y respuesta de API
- Las clases convencionales siguen siendo la mejor opción cuando predomina el comportamiento o se necesita herencia
Aprende Java con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 104
- Lecciones
- 374
Preguntas frecuentes
¿La lección «Records frente a clases y Lombok» es gratis?
Sí — el texto completo de «Records frente a clases y Lombok» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Records frente a clases y Lombok»?
Compare los records con las clases tradicionales y las anotaciones de Lombok para elegir la herramienta adecuada. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Records frente a clases y Lombok»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Introducción a los records
- Constructores compactos y validación
- Métodos personalizados en records
- Records frente a clases y Lombok