JavaRush/Java блог/Java Developer/Библиотека Lombok
Сергей
40 уровень

Библиотека Lombok

Статья из группы Java Developer
участников
Библиотека Lombok сокращает количество написанного кода, улучшая читаемость. Библиотека Lombok - 1Пример использования. Обычный класс Person c тремя полями:
public class Person {

    private String name;
    private int age;
    private Cat cat;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name) &&
                Objects.equals(cat, person.cat);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, cat);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", cat=" + cat +
                '}';
    }
}
Тоже самое с lombok
@Data
public class Person {
    private String name;
    private int age;
    private Cat cat;
}
Мы убрали кучу кода, однако, все методы и модификаторы остались. Как это работает. Lombok генерирует код на этапе компиляции. Сама библиотека lombok отсутствует в рантайме. Ее использование не увеличивает размер программы. При использовании Lombok наш исходный код не будет валидным кодом Java. Поэтому потребуется установить плагин для IDE, иначе среда разработки не поймёт, с чем имеет дело. Lombok поддерживает все основные Java IDE. Интеграция бесшовная. Все функции вроде «показать использования» и «перейти к реализации» продолжают работать как и раньше, перемещая вас к соответствующему полю/классу. Итак, для простых классов можно воспользоваться аннотацией @Data. @Data - генерирует конструктор, геттеры, сеттеры, методы equals, hashCode, toString. Чтобы сделать объекты неизменяемыми есть @Value. @Value - генерирует конструктор, только геттеры, методы equals, hashCode, toString. А также делает все поля private и final.
@Value
public class Cat {
    String name;
    int age;
    Person person;
}
С неизменяемыми классами хорошо сочетаются аннотации @With и @Builder.
@With
@Builder
@Value
public class Cat {
    String name;
    int age;
    Person person;
}
Если мы хотим у неизменяемого объекта поменять поле, то нам нужно сделать клон этого объекта с одним измененным параметром. @With - добавляет методы для каждого поля, которые делают клон объекта с одним измененным полем.
Cat anotherCat = cat.withName("Вася");
anotherCat - новый объект у которого значения полей такие же как у cat, кроме поля name. @Builder - генерирует методы, которыми мы инициализируем объект по цепочке. Это удобно когда мы не хотим использовать конструктор со всеми параметрами (Если у нас класс неизменяемый, то в нем единственный конструктор со всеми параметрами).
Cat cat = Cat.builder()
                .name("Мурка")
                .age(3)
                .person(person)
                .build();
Цикличный вызов методов Если объекты имеют двунаправленную связь, т.е. ссылки друг на друга, то использование методов toString, equals и hashCode приведет к ошибке StackOverflowError. Т.к. будет цикличный вызов методов вложенных объектов. Данный код приведет к ошибке:
public class Main {

    public static void main(String[] args) {
        Person person = new Person();

        Cat cat = Cat.builder()
                .name("Мурка")
                .age(3)
                .person(person)
                .build();

        person.setName("Иван");
        person.setAge(26);
        person.setCat(cat);

        System.out.println(person);
        System.out.println(cat);
    }
}
Решение проблемы - прервать цикличный вызов, убрав из метода поле. @ToString.Exclude - Исключить поле в методе toString @EqualsAndHashCode.Exclude - Исключить поле в методе equals и hashCode
@Value
@With
@Builder
public class Cat {
    String name;
    int age;
    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    Person person;
}
Еще пара полезных аннотаций @Slf4j - добавляет в класс логгер log @SneakyThrows - делает проверяемые исключения непроверяемыми
@Slf4j
public class Main {

    @SneakyThrows
    public static void main(String[] args) {
        log.info("start");
        Files.readAllBytes(Paths.get(""));
    }
}
Аннотации по отдельности Если по каким-либо причинам вам нужны только определенные методы
@NoArgsConstructor //добавляет конструктор без аргументов
@AllArgsConstructor //добавляет конструктор со всеми параметрами
@RequiredArgsConstructor //добавляет конструктор для final полей
@Getter //добавляет геттеры для всех параметров класса
@Setter //добавляет сеттеры для всех параметров класса
@EqualsAndHashCode //добавляет реализации методов equals и hashCode
@ToString //добавляет реализацию метода toString
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) //делает все поля private и final
Библиотека Lombok - 2<h2>Заключение</h2>Это только основные аннотации lombok, но они чаще всего используются и дают максимальный эффект. Слишком сильно увлекаться генерацией кода тоже не стоит. <h2>Ссылки</h2>
Комментарии (8)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Anonymous #3162843
Уровень 18
2 апреля 2023, 16:51
Что значит @Slf4j - добавляет в класс логгер log,может кто-нибудь подробнее рассказать об этом
Сергей Java Developer в Сбер Expert
29 мая 2023, 14:12
Эта аннотация неявно добавляет строку private static final Logger log = Logger.getLogger(Example.class);
Artur
Уровень 23
16 февраля 2022, 21:33
Забыли про @Accessors(chain = true) - позволяет сеттерам возвращать объект и выстраивать его в цепочку для присвоения значений, как делает это Builder.
Vladimir Komarov QA Automation Engineer
4 июня 2020, 10:03
Убираем геттеры-сеттеры, но добавляем кучку анонотаций и необходимость поддержки всего этого. Так себе инфраструктурная затея.
Сергей Java Developer в Сбер Expert
4 июня 2020, 10:24
В большинстве случаев все ограничивается 1-2 аннотациями, которые сокращают код строк так на 100. В любом случае эта библиотека использовалась на всех проектах, на которых я работал.
Justinian Judge в Mega City One Master
5 июня 2020, 07:52
но добавляем кучку анонотаций и необходимость поддержки всего этого
это ты про спринг или ломбок? 🤣
Pavel Kurchavov Support Engineer в Ozon.ru
8 февраля 2021, 16:51
есть у нас 50 полей. убираем геттеры сеттеры (100 штук всего), добавляем 2 аннотации. Удобно же)
partiec
Уровень 33
9 сентября 2023, 19:52
Поля пиши вверху. Глянул и все. Дальше вниз не прокручивай. Не надо благодарить.