Lombok Annotations

Project Lombok is a Java library that can be used to reduce boilerplate code in Java applications. Lombok provides a set of annotations that can be used to automatically generate common code patterns such as getters, setters, constructors, and toString methods.

Here are some of the most commonly used Lombok annotations:

@Getter and @Setter

The Lombok @Getter and @Setter annotations are used to automatically generate getter and setter methods for fields in a Java class.

The @Getter annotation generates a getter method for each non-static, non-final field in the class, while the @Setter annotation generates a setter method for each non-static, non-final field.

Here is an example of how to use the @Getter and @Setter annotations:

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

This code will generate a class equivalent to:

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

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

@NoArgsConstructor, @RequiredArgsConstructor, and @AllArgsConstructor:

These annotations are used to generate constructors for a class.

  • The @NoArgsConstructor annotation generates a constructor with no arguments.
  • The @RequiredArgsConstructor annotation generates a constructor with arguments for final fields and fields annotated with @NonNull.
  • The @AllArgsConstructor annotation generates a constructor with arguments for all non-static, non-final fields.

Here is an example of how to use the annotations:

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@RequiredArgsConstructor
@AllArgsConstructor
public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private final String id;
    private final String nationalId;
}

This code will generate a class equivalent to:

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private final String id;
    private final String nationalId;

    protected Person() {
    }

    public Person(String id, String nationalId) {
        this.id = id;
        this.nationalId = nationalId;
    }

    public Person(String firstName, String lastName, int age, String id, String nationalId) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.id = id;
        this.nationalId = nationalId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

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

    public String getId() {
        return id;
    }

    public String getNationalId() {
        return nationalId;
    }

}

It’s important to notice that when using @NoArgsConstructor, @RequiredArgsConstructor, and @AllArgsConstructor together, the order of the annotations matters. It’s also possible to use the @NoArgsConstructor(access = AccessLevel.PROTECTED) to generate a protected no-args constructor. The access level for the constructors can be specified by using the access parameter, for example, @AllArgsConstructor(access = AccessLevel.PRIVATE)

@ToString:

This annotation is used to generate a toString method for a class.

Here’s an example of how to use the @ToString annotation:

import lombok.ToString;

@ToString
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

This will generate a toString() method equivalent to:

@Override
public String toString() {
    return "Person(firstName=" + this.firstName + ", lastName=" + this.lastName + ", age=" + this.age + ")";
}

It’s also possible to customize the generated toString() method by providing various options to the annotation, such as including or excluding specific fields, specifying a custom style, or providing a custom method name.

Here’s an example:

@ToString(exclude = "age")
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

In this case, the age field will not be included in the generated toString method.

@EqualsAndHashCode:

This annotation is used to generate equals and hashCode methods for a class.

Here’s an example of how to use the @EqualsAndHashCode annotation:

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

This will generate an equals(Object other) method that compares the fields of the class for equality and a hashCode() method that calculates a hash code based on the fields of the class.

It’s also possible to customize the generated methods by providing various options to the annotation, such as including or excluding specific fields, or providing a custom method name.

Here’s an example:

@EqualsAndHashCode(exclude = "age")
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

In this case, the age field will not be included in the generated equals and hashCode methods.

It’s important to note that, the default behavior of the generated equals method is to only compare the non-transient, non-static fields of the class, and it’s not a deep comparison.

@Data

The Lombok @Data annotation is a shortcut annotation that combines the functionality of several other Lombok annotations, including @Getter, @Setter, @ToString, @EqualsAndHashCode, and @RequiredArgsConstructor.

When applied to a class, Lombok generates the following for that class:

  • Getter and setter methods for all non-static, non-final fields.
  • A toString method that prints the class name and the values of all fields
  • An equals and hashCode method based on all non-static, non-transient fields
  • A constructor with all fields as arguments, including final fields

Here is an example of how to use the @Data annotation:

import lombok.Data;

@Data
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

This code will generate a class equivalent to:

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return this.age;
    }

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

    public boolean equals(final Object o) {
        if (o == this) return true;
        if (!(o instanceof Person)) return false;
        final Person other = (Person) o;
        if (!other.canEqual((Object) this)) return false;
        final Object this$firstName = this.getFirstName();
        final Object other$firstName = other.getFirstName();
        if (this$firstName == null ? other$first

@Value

The Lombok @Value annotation is used to automatically generate an immutable class. When applied to a class, Lombok generates the following for that class:

  • A private final field for each non-static, non-transient field.
  • A constructor with all final fields as arguments.
  • Getters for all fields.
  • Equals, hashCode and toString methods based on all fields.

Here is an example of how to use the @Value annotation:

import lombok.Value;

@Value
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

This code will generate a class equivalent to:

public final class Person {
    private final String firstName;
    private final String lastName;
    private final int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public int getAge() {
        return this.age;
    }

    public boolean equals(final Object o) {
        if (o == this) return true;
        if (!(o instanceof Person)) return false;
        final Person other = (Person) o;
        if (!other.canEqual((Object) this)) return false;
        final Object this$firstName = this.getFirstName();
        final Object other$firstName = other.getFirstName();
        if (this$firstName == null ? other$firstName != null : !this$firstName.equals(other$firstName)) return false;
        final Object this$lastName = this.getLastName();
        final Object other$lastName = other.getLastName();
        if (this$lastName == null ? other$lastName != null : !this$lastName.equals(other$lastName)) return false;
        if (this.getAge() != other.getAge()) return false;
        return true;
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Person;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $firstName = this

@Builder:

The Lombok @Builder annotation is used to create a builder-style object creation pattern for a class. It generates a builder class with methods for setting each field of the class, as well as a build method for creating an instance of the class with the current field values.

Here’s an example of how to use the @Builder annotation:

import lombok.Builder;

@Builder
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

This will generate a PersonBuilder class with methods for setting each field of the Person class, as well as a build method for creating an instance of the Person class with the current field values.

Here’s an example of how to use the generated builder to create an instance of the Person class:

Person person = Person.builder().firstName("John").lastName("Doe").age(30).build();

@Slf4j

The Lombok @Slf4j annotation is used to automatically add a private static final field of type org.slf4j.Logger and a corresponding getter for the field in the class. This allows you to use the Simple Logging Facade for Java (SLF4J) for logging in your class without having to manually create a Logger instance and keep track of it.

Here’s an example of how to use the @Slf4j annotation:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyClass {
    public void myMethod() {
        log.info("This is an info message");
    }
}

This will add the following field to your class:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MyClass.class);

And you can use the log variable to log messages, for example:

log.debug("This is a debug message");
log.info("This is an info message");
log.warn("This is a warning message");
log.error("This is an error message");

It is important to note that for using the @Slf4j annotation, you need to have slf4j-api and a binding (e.g. logback, log4j2) in your classpath.

@Cleanup

The Lombok @Cleanup annotation is used to automatically close a resource after it’s no longer needed. This helps to ensure that resources are properly closed, even in the presence of exceptions or errors.

Here’s an example of how to use the @Cleanup annotation:

import java.io.FileInputStream;
import lombok.Cleanup;

public class MyClass {
    public void myMethod() throws Exception {
        @Cleanup FileInputStream fis = new FileInputStream("file.txt");
        // use the file input stream
    }
}

In this example, when the myMethod method exits, the fis.close() method will be called automatically. This helps to avoid the common problem of resources not being closed, which can lead to resource leaks and other issues.

It’s also possible to use the cleanup annotation with try-with-resources statement, in this case, the annotation is not needed.

public class MyClass {
    public void myMethod() throws Exception {
        try (FileInputStream fis = new FileInputStream("file.txt")) {
            // use the file input stream
        }
    }
}

It’s worth noting that the @Cleanup annotation only works with resources that implement the java.io.Closeable interface, and only for local variables.

Leave a Reply

Your email address will not be published. Required fields are marked *