Lombok is a Java library that helps developers eliminate boilerplate code by generating it automatically using annotations. It leads to cleaner and more maintainable code. In this comprehensive guide, we’ll explore all the features available in Lombok and how to use them effectively.

Setting Up Lombok

To start using Lombok, add the following dependency to your build configuration:

<!-- For Maven -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>
// For Gradle
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'

Features

1. @Getter and @Setter

Lombok generates getter and setter methods for class fields using the @Getter and @Setter annotations. These annotations can be placed on individual fields or on the class.

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

2. @ToString

The @ToString annotation generates a toString() method, providing a readable string representation of the object.

@Getter
@Setter
@ToString
public class Person {
    private String name;
    private int age;
}

3. @EqualsAndHashCode

The `@EqualsAndHashCode` annotation generates `equals()` and `hashCode()` methods, ensuring proper comparison and hashing behavior for the class.

@Getter
@Setter
@ToString
@EqualsAndHashCode
public class Person {
    private String name;
    private int age;
}

4. @NoArgsConstructor, @AllArgsConstructor, and @RequiredArgsConstructor

These annotations generate constructors for your class:

  • @NoArgsConstructor: generates a no-argument constructor
  • @AllArgsConstructor: generates a constructor with arguments for all fields
  • @RequiredArgsConstructor: generates a constructor for fields marked with @NonNull
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class Person {
    @NonNull
    private String name;
    private int age;
}

5. @Data

The @Data annotation is a shortcut for applying @Getter, @Setter, @ToString, @EqualsAndHashCode, and @RequiredArgsConstructor annotations.

@Data
public class Person {
    @NonNull
    private String name;
    private int age;
}

6. @Builder

The @Builder annotation generates a builder pattern implementation, allowing for fluent object creation.

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

// Usage
Person person = Person.builder().name("John Doe").age(30).build();

7. @Slf4j, @Log, and other logging annotations

Lombok provides annotations to generate a logger instance for various logging frameworks:

  • @Slf4j: for SLF4J
  • @Log: for Java Util Logging
  • @Log4j: for Log4j
  • @Log4j2: for Log4j2
@Slf4j
public class PersonService {
    public void doSomething() {
        log.info("Doing something...");
    }
}

8. @Cleanup

The @Cleanup annotation ensures that a resource is closed after use, avoiding resource leaks.

public void readFromFile(String fileName) throws IOException {
    @Cleanup InputStream inputStream = new FileInputStream(fileName);
    // Do something with inputStream
}

9. @Synchronized

The @Synchronized annotation generates a synchronized version of the method and uses a private lock object to prevent concurrency issues.

@Synchronized
public void incrementCounter() {
    counter++;
}

10. @Delegate

The @Delegate annotation generates delegate methods for an interface or superclass, delegating the method calls to an instance field.

public interface NameRetriever {
    String getName();
}

public class PersonDelegate implements NameRetriever {
    private final Person person;

    @Delegate
    private NameRetriever getNameRetriever() {
        return person::getName;
    }
}

11. @Value

The @Value annotation generates an immutable class with final fields, a constructor for all fields, and getter methods.

@Value
public class ImmutablePerson {
    String name;
    int age;
}

12. @With

The @With annotation generates “with” methods that return a new instance of the class with a modified field value, useful for immutable classes.

@Value
public class ImmutablePerson {
    @With
    String name;
    @With
    int age;
}

13. @FieldNameConstants

The @FieldNameConstants annotation generates a class with constants representing field names, which can be useful in situations where you need to refer to field names in a type-safe manner, such as when working with database queries or mapping libraries.

@FieldNameConstants
public class Person {
    private String name;
    private int age;
}

// Usage
String fieldName = Person.Fields.name;

14. @SuperBuilder

The @SuperBuilder annotation is an extension of @Builder and is designed to work with inheritance. It generates builder classes for the superclass and its subclasses, allowing you to create objects with inherited fields.

@SuperBuilder
public class Person {
    private String name;
    private int age;
}

@SuperBuilder
public class Employee extends Person {
    private String jobTitle;
}

// Usage
Employee employee = Employee.builder().name("John Doe").age(30).jobTitle("Developer").build();

15. @UtilityClass

The @UtilityClass annotation marks a class as a utility class by generating a private constructor to prevent instantiation and making all its members static.

@UtilityClass
public class MathUtils {
    public int add(int a, int b) {
        return a + b;
    }
}

// Usage
int sum = MathUtils.add(2, 3);

16. @ExtensionMethod

The @ExtensionMethod annotation allows you to extend existing classes with new methods in a non-invasive way by simulating extension methods from languages like Kotlin or C#. The new methods are defined in separate utility classes.

public class StringUtils {
    public static String reverse(String input) {
        return new StringBuilder(input).reverse().toString();
    }
}

// Usage
@ExtensionMethod(StringUtils.class)
public class StringExtensionsDemo {
    public void demo() {
        String reversed = "hello".reverse();
        System.out.println(reversed); // Output: "olleh"
    }
}

Conclusion

Lombok offers a wide array of features to simplify Java development and reduce boilerplate code. By using annotations such as @Getter, @Setter, @ToString, and @Builder, you can generate essential methods automatically, resulting in cleaner and more maintainable code.

Additionally, Lombok provides support for logging with various frameworks, ensures proper resource cleanup, and simplifies concurrency with the @Synchronized annotation. Immutable classes can be easily created with the @Value and @With annotations, promoting safer and more robust code.

It’s essential to understand that Lombok uses annotation processing to generate code at compile-time. Therefore, it doesn’t introduce any runtime overhead. However, it’s worth noting that using Lombok may cause issues with some IDEs or build tools, so it’s crucial to ensure compatibility before adopting it in your projects.

Overall, Lombok is a powerful tool that helps you write more efficient and cleaner Java code, allowing you to focus on the core functionality of your application.