Привет, Хабр!

Если вы писали на Java хоть раз, то знаете этот ужас — бесконечные геттеры, сеттеры, конструкторы, да ещё toString() и equals() на закуску. Одной только стандартной обвязки в классах моделей больше, чем самого кода.

Lombok — это библиотека, которая берёт всё это бойлерплейтное безумие и оставляет только чистую суть.

Что делает Lombok?

  • Генерирует геттеры, сеттеры, toString(), equals() и другие методы автоматически.

  • Упрощает создание конструкторов и билдеров.

  • Уменьшает количество кода в разы.

Например:

public class User {
    private String username;
    private String email;

    public User() {}

    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }

    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    @Override
    public String toString() {
        return "User{" + "username='" + username + '\'' + ", email='" + email + '\'' + '}';
    }
}

15 строк. Ради двух полей.

То же самое, но с Lombok:

import lombok.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String username;
    private String email;
}

И все. Три аннотации заменили 15 строк шаблонного кода.

Lombok использует аннотации, которые на этапе компиляции добавляют в код всю скучную обвязку. Это происходит на уровне APT.

При компиляции Lombok генерирует дополнительные методы прямо в байткод, поэтому на runtime его вообще нет. Это значит, что:

  1. IDE может видеть и использовать эти методы.

  2. Никаких зависимостей в коде.

  3. Скорость работы не страдает.

Но есть и нюансы, например, IDE должна поддерживать Lombok.

Аннотаций Lombok

@Getter и @Setter

Было:

public class User {
    private String name;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

Стало:

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {
    private String name;
}

Теперь getName() и setName() автоматически создаются компилятором.

Но если вдруг нужно только геттер, но без сеттера, можно сделать так:

@Getter
public class ImmutableUser {
    private final String username;
}

Теперь username можно читать, но нельзя изменять — удобно для иммутабельных объектов.

@ToString — избавляет от ручного написания toString()

Было:

public class Product {
    private String name;
    private double price;

    @Override
    public String toString() {
        return "Product{name='" + name + "', price=" + price + "}";
    }
}

Стало:

import lombok.ToString;

@ToString
public class Product {
    private String name;
    private double price;
}

Теперь System.out.println(product); автоматически выведет что‑то вроде:

Product(name=iPhone, price=999.99)

Можно даже исключить поля из toString():

@ToString(exclude = "password")
public class Account {
    private String username;
    private String password;
}

@EqualsAndHashCode — избавляет от ручного написания equals() и hashCode()

Эта аннотация делает объекты сравнимыми:

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class Customer {
    private int id;
    private String name;
}

Теперь new Customer(1, "Alice").equals(new Customer(1, "Alice")) вернёт true.

Если нужно исключить поле (например, не учитывать id в сравнении):

@EqualsAndHashCode(exclude = "id")
public class Customer {
    private int id;
    private String name;
}

@Data — универсальная аннотация

Хотите всё сразу? @Data объединяет:

  • @Getter

  • @Setter

  • @EqualsAndHashCode

  • @ToString

  • @RequiredArgsConstructor

import lombok.Data;

@Data
public class Order {
    private String product;
    private int quantity;
}

Теперь:

  • Геттеры и сеттеры есть.

  • toString() есть.

  • equals() и hashCode() тоже есть.

И никаких лишних строк.

Настройка Lombok в проекте

Сначала подключим в Maven. Добавляем в pom.xml:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Подключение в Gradle:

dependencies {
    compileOnly 'org.projectlombok:lombok:1.18.26'
    annotationProcessor 'org.projectlombok:lombok:1.18.26'
}

Включаем в IntelliJ IDEA:

  • Устанавливаем плагин Lombok (Preferences → Plugins → Lombok Plugin).

  • Включаем аннотации в Settings → Compiler → Annotation Processors.

Теперь IDE понимает Lombok.

А вы используете Lombok в своих проектах? Или пишете геттеры и toString() в ручную? Делитесь в комментариях.


Разработчикам на Java рекомендую обратить внимание на открытые уроки, которые пройдут в феврале в Otus:

  • 12 февраля: «Resilience4j. Bulkhead»
    Познакомимся с библиотекой Resilience4j и рассмотрим Bulkhead для защиты приложений от перегрузок. Записаться

  • 24 февраля: «Resilience4j. RateLimiter»
    Познакомимся с библиотекой Resilience4j и рассмотрим RateLimiter для контроля нагрузки и защиты микросервисов. Записаться

Комментарии (20)


  1. gev
    06.02.2025 13:25

    Но если вдруг нужно только геттер, но без сеттера, можно сделать так:

    @Getterpublic class ImmutableUser {    private final String username;}

    Теперь username можно читать, но нельзя изменять — удобно для иммутабельных объектов.

    А что мешает сделать поле просто публичным?


    1. PrinceKorwin
      06.02.2025 13:25

      Сделав публичным вы также позволите его менять. Речь же, как я понял, про то, что после инстанциации объекта поле уже нельзя поменять.


      1. gev
        06.02.2025 13:25

        оно же `final`


        1. PrinceKorwin
          06.02.2025 13:25

          Да. Не защищая Lombok. Но такие get/set методы бывают удобны чтобы в отладке брейкпоинт поставить.

          Правда Lombok с отладкой не очень дружит.


  1. BugM
    06.02.2025 13:25

    Рекорды - просто существуют.


    1. Conung_ViC
      06.02.2025 13:25

      ломбок был тогда, когда рекордов еще не было


      1. BugM
        06.02.2025 13:25

        За моим окном 2025 статья свежая и рекорды уже есть. А за вашим окном какой год?


        1. mastercode
          06.02.2025 13:25

          Тот, в котором более 60% java проектов используют java ниже 17 версии )

          https://newrelic.com/resources/report/2024-state-of-the-java-ecosystem

          Учитывая что не-lts версии используют менее 2%, более 60% проектов используют java 8 и 11 )


          1. osigida
            06.02.2025 13:25

            после 8ой версии уже вышло много LTS
            https://www.oracle.com/java/technologies/java-se-support-roadmap.html


          1. BugM
            06.02.2025 13:25

            У тех кто не обновился до хотя бы 17 такой кровавый энтерпрайз что им тоже не надо. Новичковые статьи про Ломбук их разработчикам точно не нужны. И их джунам (не уверен что они ниже мидлов нанимают вообще) не нужны.

            У меня в окрестностях включая знакомых весь энтерпрайз уже до 17 обновился. Про 21 думают и местами катят, но еще нет. Может где-то в недрах нефтегаза разве что осталась джава <17.


            1. Scott_Leopold
              06.02.2025 13:25

              В Сбере полно 8 и 11


              1. sergey-gornostaev
                06.02.2025 13:25

                Но это не норма, а недоработки на местах, судя по тому, что в моих проектах зарегистрировали работу на 8-ке как архитектурное отклонение и поставили в план обновляться на 17-ю.


    1. ris58h
      06.02.2025 13:25

      В статье, хоть она весьма скудная и раскрывает только малую часть того на что способен Lombok, затрагиваются проблемы помимо иммутабельных объектов.


      1. BugM
        06.02.2025 13:25

        Если вы писали на Java хоть раз, то знаете этот ужас — бесконечные геттерысеттерыконструкторы, да ещё toString() и equals() на закуску. Одной только стандартной обвязки в классах моделей больше, чем самого кода.

        Ага, конечно.

        Ответом на первый абзац является одно предложение: Используйте рекорды. Везде. Даже вместо привычного Pair делайте рекорд. Эти три строки кода делающие рекорд вместо Pair невероятно полезны.

        Рекорды не только работают быстрее, но еще и улучшат стиль вашего кода и уменьшат количество багов с мутабельным стейтом.


        1. ris58h
          06.02.2025 13:25

          Используйте рекорды. Везде.

          Расскажите, пожалуйста, как использовать рекорды в качестве Entity в Hibernate?


          1. DenSigma
            06.02.2025 13:25

            Hibernat, кстати, тоже дрянь аналогично ломбоку. Присматриваюсь к SpringDataJDBC, и в нем, между прочим, рекорды использовать можно.


  1. SimSonic
    06.02.2025 13:25

    Прям коробит, когда люди навешивают к @Data AAC и NAC бездумно, типа мол пусть будет. @Data и так включает RAC, который в зависимости от наличия final на полях всё сделает в лучшем виде.

    Но юзать @Data желательно ... только лишь нигде и никогда. Гораздо предпочтительнее иммутабельный аналог -- @Value, который нельзя повешать разве только на JPA сущности, но так и @Data в них тоже не выстреливает проблемами только в простых случаях.

    Ну и да, Accessors, Builder/SuperBuilder, UtilityClass, SneakyThrows, lombok.config и много чего ещё -- вообще не упомянуто. Поэтому за статью минус.