0Pricing
Java Academy · Lezione

Record, classi e Lombok a confronto

Confronti i record con le classi tradizionali e le annotazioni Lombok per scegliere lo strumento più adatto.

Record, classi e Lombok a confronto è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Record rispetto a classi e Lombok

Java offre diversi approcci per creare tipi che trasportano dati: classi semplici con codice ripetitivo, record (Java 16+) oppure annotazioni Lombok. La scelta più adatta dipende dal caso d'uso.

Il problema del codice ripetitivo

Una semplice classe Java per trasportare dati richiede molto codice ripetitivo: costruttore, metodi di accesso, equals, hashCode e toString, tutto questo per appena pochi campi.

// 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 soluzione dei record

Un record riduce la stessa classe a una sola riga. Il compilatore genera automaticamente tutto il codice ripetitivo.

// 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 e @Value

Lombok genera il codice ripetitivo in fase di compilazione tramite annotazioni. @Value crea una classe immutabile simile ai record; @Data crea una classe mutabile.

// 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
}

Differenze principali

Differenze importanti tra Records, Lombok @Value e classi normali:

  • Convenzione di denominazione degli accessor: i Records utilizzano name(); Lombok utilizza getName()
  • Variante mutabile: i Records sono sempre immutabili; Lombok offre @Data per la mutabilità
  • Ereditarietà: i Records non possono estendere classi; le classi Lombok possono farlo
  • Dipendenza dallo strumento di build: Lombok richiede la configurazione di un annotation processor; i Records sono integrati nel linguaggio

Quando utilizzare i Records

I Records sono ideali quando:

  • Il tipo è principalmente un contenitore trasparente di dati (DTO, Value Object)
  • Si desidera progettualmente l'immutabilità
  • Si utilizza Java 16 o versione successiva e si desidera evitare dipendenze
  • Il tipo partecipa al 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 state

Quando utilizzare Lombok

Lombok è preferibile quando:

  • Sono necessari bean mutabili (ad esempio entità JPA o classi di configurazione Spring)
  • La denominazione degli accessor deve seguire la convenzione JavaBeans (getX) per garantire la compatibilità con i framework
  • È necessario @Builder per costruire oggetti complessi
  • È necessaria una mutabilità parziale (@NonFinal su alcuni campi)
// 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();

Quando utilizzare le classi normali

Le classi normali restano appropriate quando:

  • La classe presenta un comportamento complesso che va oltre il semplice contenimento di dati
  • È necessario estendere un'altra classe
  • È richiesto un controllo dettagliato su hashCode/equals
  • È necessario uno stato mutabile con incapsulamento
// 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(); }
}

Combinare Records e classi

Records e classi funzionano perfettamente insieme. Utilizzi i Records per i dati immutabili all'interno di classi che gestiscono uno stato mutabile.

// 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();
    }
}

I Records in Spring Boot

I Records si integrano bene con Spring Boot come corpi delle richieste e delle risposte. Il mapper Jackson di Spring li gestisce con una configurazione minima.

// 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());
    }
}

Confronto delle prestazioni

Tutti e tre gli approcci producono essenzialmente lo stesso bytecode per semplici contenitori di dati. Le prestazioni sono identiche: la scelta dipende dall'esperienza dello sviluppatore e dai requisiti.

// 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 module

Verifica rapida

Quale convenzione di denominazione seguono gli accessor dei Records?

Riepilogo: Records, classi e Lombok a confronto

Punti chiave:

  • I Records generano automaticamente il costruttore, gli accessor (senza prefisso get), equals, hashCode e toString
  • I Records sono sempre immutabili; utilizzi le classi normali per lo stato mutabile
  • Lombok @Value è simile ai Records, ma utilizza la denominazione getX e richiede una configurazione
  • Lombok @Builder è particolarmente adatto alla costruzione di oggetti complessi con molti campi opzionali
  • I Records sono ideali per DTO, value object e corpi delle richieste e delle risposte API
  • Le classi normali restano la scelta migliore quando prevale il comportamento o è necessaria l'ereditarietà

Domande Frequenti

La lezione «Record, classi e Lombok a confronto» è gratuita?

Sì — il testo completo di «Record, classi e Lombok a confronto» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Record, classi e Lombok a confronto»?

Confronti i record con le classi tradizionali e le annotazioni Lombok per scegliere lo strumento più adatto. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Record, classi e Lombok a confronto»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Introduzione ai record
  2. Costruttori compatti e validazione
  3. Metodi personalizzati nei record
  4. Record, classi e Lombok a confronto
← Torna a Java Academy