0Pricing
Java Academy · Lekcja

Rekordy a klasy i Lombok

Porównuj rekordy z tradycyjnymi klasami i adnotacjami Lombok, aby wybrać właściwe narzędzie.

Rekordy a klasy i Lombok to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Rekordy a klasy i Lombok

Java oferuje kilka sposobów tworzenia typów przenoszących dane: zwykłe klasy z kodem pomocniczym, rekordy (Java 16+) lub adnotacje Lombok. Wybór właściwego rozwiązania zależy od przypadku użycia.

Problem nadmiarowego kodu

Zwykła klasa Java będąca prostym nośnikiem danych wymaga znacznej ilości kodu pomocniczego: konstruktora, metod dostępowych, equals, hashCode i toString — a wszystko to zaledwie dla kilku pól.

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

Rozwiązanie w postaci rekordu

Rekord skraca tę samą klasę do jednego wiersza. Kompilator automatycznie generuje cały kod pomocniczy.

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

Lombok generuje kod pomocniczy podczas kompilacji za pomocą adnotacji. @Value tworzy niezmienną klasę podobną do rekordów, a @Data tworzy klasę zmienną.

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

Najważniejsze różnice

Najważniejsze różnice między rekordami, Lombok @Value a zwykłymi klasami:

  • Nazewnictwo akcesorów: rekordy używają name(), a Lombok — getName()
  • Wariant mutowalny: rekordy są zawsze niemutowalne, natomiast Lombok udostępnia @Data do tworzenia obiektów mutowalnych
  • Dziedziczenie: rekordy nie mogą rozszerzać klas, a klasy Lombok mogą
  • Zależność od narzędzia budującego: Lombok wymaga konfiguracji procesora adnotacji, natomiast rekordy są wbudowane w język

Kiedy używać rekordów

Rekordy są idealne, gdy:

  • Typ służy przede wszystkim jako przejrzysty nośnik danych (DTO, Value Object)
  • Z założenia wymagana jest niemutowalność
  • Używają Państwo Java 16 lub nowszej wersji i chcą uniknąć zależności
  • Typ uczestniczy w dopasowywaniu wzorców (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

Kiedy używać Lombok

Lombok jest preferowany, gdy:

  • Potrzebne są mutowalne beany (np. encje JPA lub klasy konfiguracyjne Spring)
  • Nazewnictwo akcesorów musi być zgodne z konwencją JavaBeans (getX) ze względu na zgodność z frameworkami
  • Potrzebują Państwo @Builder do konstruowania złożonych obiektów
  • Wymagana jest częściowa mutowalność (@NonFinal dla wybranych pól)
// 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();

Kiedy używać zwykłych klas

Zwykłe klasy pozostają odpowiednie, gdy:

  • Klasa zawiera złożone zachowanie wykraczające poza proste przechowywanie danych
  • Trzeba rozszerzyć inną klasę
  • Potrzebna jest szczegółowa kontrola nad implementacją hashCode/equals
  • Wymagany jest mutowalny stan z zachowaniem enkapsulacji
// 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(); }
}

Łączenie rekordów i klas

Rekordy i klasy współpracują ze sobą bez problemu. Rekordów należy używać do przechowywania niemutowalnych danych wewnątrz klas zarządzających mutowalnym stanem.

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

Rekordy w Spring Boot

Rekordy dobrze integrują się z Spring Boot jako ciała żądań i odpowiedzi. Mapper Jacksona używany przez Spring obsługuje je przy minimalnej konfiguracji.

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

Porównanie wydajności

Wszystkie trzy podejścia generują zasadniczo taki sam bytecode dla prostych nośników danych. Wydajność jest identyczna — wybór zależy od komfortu programistów i wymagań.

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

Szybkie sprawdzenie

Jaką konwencję nazewnictwa stosują akcesory rekordów?

Podsumowanie: rekordy a klasy i Lombok

Najważniejsze informacje:

  • Rekordy automatycznie generują konstruktor, akcesory (bez prefiksu get), equals, hashCode i toString
  • Rekordy są zawsze niemutowalne; do przechowywania mutowalnego stanu należy używać zwykłych klas
  • Lombok @Value w przybliżeniu odwzorowuje rekordy, ale używa nazewnictwa getX() i wymaga konfiguracji
  • Lombok @Builder sprawdza się przy konstruowaniu złożonych obiektów z wieloma opcjonalnymi polami
  • Rekordy są idealne dla DTO, obiektów wartości oraz ciał żądań i odpowiedzi API
  • Zwykłe klasy pozostają najlepszym wyborem, gdy najważniejsze jest zachowanie lub potrzebne jest dziedziczenie

Często zadawane pytania

Czy lekcja „Rekordy a klasy i Lombok” jest bezpłatna?

Tak — pełny tekst „Rekordy a klasy i Lombok” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Rekordy a klasy i Lombok”?

Porównuj rekordy z tradycyjnymi klasami i adnotacjami Lombok, aby wybrać właściwe narzędzie. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Rekordy a klasy i Lombok”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wprowadzenie do rekordów
  2. Kompaktowe konstruktory i walidacja
  3. Własne metody w rekordach
  4. Rekordy a klasy i Lombok
← Powrót do Java Academy