Java Academy · Lektion

Records vs. klasser vs. Lombok

Sammenlign records med traditionelle klasser og Lombok-annotationer, så De kan vælge det rette værktøj.

Lektion 4 af 413 trin

Records vs. klasser vs. Lombok er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.

Record-typer kontra klasser kontra Lombok

Java tilbyder flere tilgange til at oprette datatransporterende typer: almindelige klasser med standardkode, records (Java 16+) eller Lombok-annotationer. Det rigtige valg afhænger af anvendelsen.

Problemet med standardkode

En almindelig Java-klasse til en simpel datatransportør kræver meget standardkode: konstruktør, gettere, equals, hashCode og toString – alt sammen for blot nogle få felter.

// 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() { /* ... */ }
}

Record-løsningen

En record reducerer den samme klasse til én linje. Kompileren genererer automatisk al standardkoden.

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

Lombok genererer standardkode ved kompilering via annotationer. @Value opretter en uforanderlig klasse, der minder om records, mens @Data opretter en foranderlig klasse.

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

Vigtige forskelle

Vigtige forskelle mellem Records, Lombok @Value og almindelige klasser:

  • Navngivning af adgangsmetoder: Records bruger name(); Lombok bruger getName()
  • Ændringsbar variant: Records er altid uforanderlige; Lombok tilbyder @Data til ændringsbare objekter
  • Nedarvning: Records kan ikke nedarve fra klasser; Lombok-klasser kan
  • Afhængighed af byggeværktøj: Lombok kræver opsætning af en annotationsprocessor; Records er indbygget

Hvornår skal du bruge Records

Records er ideelle, når:

  • typen primært er en gennemsigtig databærer (DTO, værdiobjekt)
  • uforanderlighed er ønsket som en del af udformningen
  • du bruger Java 16 eller nyere og ønsker ingen afhængigheder
  • typen indgår i mønstermatchning (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

Hvornår skal du bruge Lombok

Lombok foretrækkes, når:

  • du har brug for ændringsbare beans (f.eks. JPA-entiteter eller Spring-konfigurationsklasser)
  • navngivningen af adgangsmetoder skal følge JavaBeans-konventionen (getX) for at være kompatibel med frameworks
  • du har brug for @Builder til kompleks oprettelse af objekter
  • der er brug for delvis ændringsbarhed (@NonFinal på bestemte felter)
// 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();

Hvornår skal du bruge almindelige klasser

Almindelige klasser er stadig velegnede, når:

  • klassen har kompleks adfærd ud over simpel databæring
  • du har brug for at nedarve fra en anden klasse
  • der er brug for detaljeret kontrol over hashCode/equals
  • der kræves en ændringsbar tilstand med indkapsling
// 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(); }
}

Kombination af Records og klasser

Records og klasser fungerer problemfrit sammen. Brug records til uforanderlige data i klasser, der håndterer en ændringsbar tilstand.

// 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 i Spring Boot

Records integreres godt med Spring Boot som anmodnings- og svarlegemer. Spring Boots Jackson-mapper håndterer dem med minimal konfiguration.

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

Sammenligning af ydeevne

Alle tre tilgange producerer stort set den samme bytekode for simple databærere. Ydeevnen er identisk — valget handler om udvikleroplevelse og krav.

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

Hurtig kontrol

Hvilken navngivningskonvention følger adgangsmetoder i records?

Opsummering: Records kontra klasser kontra Lombok

Vigtigste pointer:

  • Records genererer automatisk konstruktør, adgangsmetoder (uden get-præfiks), equals, hashCode og toString
  • Records er altid uforanderlige; brug almindelige klasser til ændringsbar tilstand
  • Lombok @Value minder om records, men bruger getX()-navngivning og kræver opsætning
  • Lombok @Builder er særligt velegnet til kompleks oprettelse af objekter med mange valgfri felter
  • Records er ideelle til DTO'er, værdiobjekter samt API-anmodnings- og svarlegemer
  • Almindelige klasser er stadig bedst, når adfærd er det vigtigste, eller når der er brug for nedarvning
Gratis at komme i gang

Lær Java med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
104
Lektioner
374

Ofte stillede spørgsmål

Er lektionen “Records vs. klasser vs. Lombok” gratis?

Ja — hele teksten til “Records vs. klasser vs. Lombok” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Records vs. klasser vs. Lombok”?

Sammenlign records med traditionelle klasser og Lombok-annotationer, så De kan vælge det rette værktøj. Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Java Academy?

Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Records vs. klasser vs. Lombok”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Java Academy-lektion?

Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Introduktion til records
  2. Kompakte konstruktører og validering
  3. Brugerdefinerede metoder på records
  4. Records vs. klasser vs. Lombok
← Tilbage til Java Academy