JavaRush /Java Blog /Random EN /Lombok Library
Сергей
Level 40
Москва

Lombok Library

Published in the Random EN group
The Lombok library reduces the amount of code written, improving readability. Lombok Library - 1Example of use. A regular class Personwith three fields:
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 +
                '}';
    }
}
Same thing with lombok
@Data
public class Person {
    private String name;
    private int age;
    private Cat cat;
}
We removed a bunch of code, however, all the methods and modifiers remained. How it works. Lombok generates code at compile time. The lombok library itself is missing in runtime. Its use does not increase the size of the program. When using Lombok, our source code will not be valid Java code. Therefore, you will need to install a plugin for the IDE, otherwise the development environment will not understand what it is dealing with. Lombok supports all major Java IDEs. The integration is seamless. All functions like "show usage" and "go to implementation" continue to work as before, taking you to the appropriate field/class. So, for simple classes you can use the annotation @Data. @Data- generates constructor, getters, setters, methods equals, hashCode, toString. To make objects immutable there is @Value. @Value- generates the constructor, only getters, methods equals, hashCode, toString. And also does all the fields privateand final.
@Value
public class Cat {
    String name;
    int age;
    Person person;
}
@WithAnnotations and .work well with immutable classes @Builder.
@With
@Builder
@Value
public class Cat {
    String name;
    int age;
    Person person;
}
If we want to change the field of an immutable object, then we need to make a clone of this object with one changed parameter. @With- adds methods for each field that make a clone of the object with one changed field.
Cat anotherCat = cat.withName("Vasya");
anotherCat- a new object whose field values ​​are the same as that of cat, except for the field name. @Builder- generates methods with which we initialize an object along a chain. This is convenient when we do not want to use a constructor with all parameters (If our class is immutable, then it has a single constructor with all parameters).
Cat cat = Cat.builder()
                .name("Мурка")
                .age(3)
                .person(person)
                .build();
Cyclic call of methods If objects have bidirectional communication, i.e. references to each other, then using the methods toStringwill equalslead hashCodeto an error StackOverflowError. Because there will be a cyclic call to methods of nested objects. This code will result in an error:
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("Ivan");
        person.setAge(26);
        person.setCat(cat);

        System.out.println(person);
        System.out.println(cat);
    }
}
The solution to the problem is to break the cyclic call by removing the field from the method. @ToString.Exclude- Exclude a field in a method toString @EqualsAndHashCode.Exclude- Exclude a field in a method equalsandhashCode
@Value
@With
@Builder
public class Cat {
    String name;
    int age;
    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    Person person;
}
A couple more useful annotations @Slf4j- adds a logger to the class @SneakyThrows- makes checked exceptions unchecked
@Slf4j
public class Main {

    @SneakyThrows
    public static void main(String[] args) {
        log.info("start");
        Files.readAllBytes(Paths.get(""));
    }
}
Annotate individually If for some reason you only need certain methods
@NoArgsConstructor //добавляет конструктор без аргументов
@AllArgsConstructor //добавляет конструктор со всеми параметрами
@RequiredArgsConstructor //добавляет конструктор для final полей
@Getter //добавляет геттеры для всех параметров класса
@Setter //добавляет сеттеры для всех параметров класса
@EqualsAndHashCode //добавляет реализации методов equals и hashCode
@ToString //добавляет реализацию метода toString
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) //делает все поля private и final
Lombok Library - 2<h2>Conclusion</h2>These are just the basic lombok annotations, but they are the most commonly used and have the greatest effect. You shouldn’t get too carried away with code generation either. <h2>Links</h2>
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION