DEV Community

Gianfranco Coppola
Gianfranco Coppola

Posted on

10 Lombok Annotations Every Java Developer Should Know

Introduction

Java is a powerful and mature language, but it comes with a cost: a lot of boilerplate code.

Think about the endless getters, setters, constructors, and toString() methods you’ve written over the years. They don’t add business value — they just make your code longer and harder to read.

That’s where Project Lombok comes to the rescue. Lombok uses annotations to generate boilerplate code at compile time, letting you focus on actual logic instead of repetitive syntax.

It integrates perfectly with Spring Boot, which makes it one of the most popular tools in modern Java development.

In this article, we’ll explore 10 Lombok annotations every Java developer should know and discuss best practices and common pitfalls so you can use Lombok effectively and safely.


How to Add Lombok to Your Project

Before you start using Lombok, make sure your project and IDE are properly configured.

Maven

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.32</version>
    <scope>provided</scope>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Gradle

compileOnly 'org.projectlombok:lombok:1.18.32'
annotationProcessor 'org.projectlombok:lombok:1.18.32'
Enter fullscreen mode Exit fullscreen mode

IDE Configuration

  • IntelliJ IDEA

    Settings > Build, Execution, Deployment > Compiler > Annotation Processors > Enable annotation processing

  • Eclipse

    Preferences > Java Compiler > Annotation Processing > Enable

  • VS Code

    1. Make sure you have the Extension Pack for Java installed (includes the Language Support for Java by Red Hat).
    2. Open your workspace settings and add: "java.configuration.annotationProcessing.enabled": true
    3. Restart VS Code and recompile the project.

Once configured, Lombok’s annotations will work seamlessly in your IDE, and you’re ready to say goodbye to boilerplate.


The 10 Most Useful Lombok Annotations

Here are the top annotations that will make your Java code cleaner, shorter, and more readable.


1. @Getter / @Setter

These annotations generate standard getter and setter methods automatically.

import lombok.Getter;
import lombok.Setter;

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

    @Getter
    private int age;
}
Enter fullscreen mode Exit fullscreen mode

At class level:

@Getter
@Setter
public class User {
    private String name;
    private int age;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Removes repetitive method definitions.
  • Keeps your classes focused on business logic.
  • You can control visibility: @Getter(AccessLevel.PROTECTED) for example.

2. @Data

Combines several Lombok annotations into one:

  • @Getter / @Setter
  • @ToString
  • @EqualsAndHashCode
  • @RequiredArgsConstructor
import lombok.Data;

@Data
public class Product {
    private final String id;
    private String name;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Great for simple DTOs and data containers.
  • Saves multiple lines of boilerplate.

When to avoid it:

  • Not ideal for JPA entities or domain models where you need more control over equality and mutability.

3. @Builder

Implements the Builder pattern, letting you create objects in a more expressive and flexible way.

import lombok.Builder;

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

// Usage
User user = User.builder()
    .name("Alice")
    .age(25)
    .build();
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Eliminates complex constructors with many parameters.

  • Improves code readability.

  • Makes object creation safe and expressive (especially in tests).


4. @AllArgsConstructor / @NoArgsConstructor

Generates constructors with all fields or no fields respectively.

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Perfect for frameworks like JPA or Jackson, which require a no-args constructor.
  • Speeds up development when dealing with DTOs or entity creation.

5. @RequiredArgsConstructor

Generates a constructor for all final fields (and those marked with @NonNull).

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class Service {
    private final Repository repository;
}
Enter fullscreen mode Exit fullscreen mode

In Spring Boot, this shines with constructor injection:

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Encourages dependency injection via constructors.
  • No need for @Autowired.
  • Promotes immutability and cleaner design.

6. @FieldDefaults (and Advanced Combo)

@FieldDefaults lets you define default modifiers for fields across a class, reducing repetitive access modifiers.

It has two main properties:

  • level → sets default access level (PRIVATE, PROTECTED, PUBLIC).
  • makeFinal → makes all fields final if true.

Example 1: Set default access level

import lombok.experimental.FieldDefaults;
import static lombok.AccessLevel.PRIVATE;

@FieldDefaults(level = PRIVATE)
public class UserService {
    String username;
    String email;
}
Enter fullscreen mode Exit fullscreen mode

Example 2: Combine with makeFinal for immutability

import lombok.experimental.FieldDefaults;
import lombok.RequiredArgsConstructor;
import static lombok.AccessLevel.PRIVATE;

@FieldDefaults(level = PRIVATE, makeFinal = true)
@RequiredArgsConstructor
public class UserService {
    UserRepository userRepository;
    NotificationService notificationService;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Keeps field definitions consistent and clean.
  • Reduces risk of accidentally exposing internal state.
  • Perfect for constructor injection when combined with @RequiredArgsConstructor.

💡 Tip: You don’t always need both properties.

Use only level for access control, or makeFinal when enforcing immutability.


7. @Value

@Value is like @Data, but it creates immutable classes:

  • All fields are private final.
  • No setters are generated.
import lombok.Value;

@Value
public class Address {
    String city;
    String zip;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Promotes immutability and thread-safety.
  • Excellent for DTOs and value objects.
  • Works perfectly with the Builder pattern.

8. @Slf4j

Generates an SLF4J logger automatically.

Without Lombok:

private static final Logger log = LoggerFactory.getLogger(MyService.class);
Enter fullscreen mode Exit fullscreen mode

With Lombok:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class OrderService {

    public void processOrder(String orderId) {
        log.info("Processing order: {}", orderId);
        try {
            // some business logic
        } catch (Exception e) {
            log.error("Error processing order {}", orderId, e);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • No more manual logger setup.
  • Fully compatible with Spring Boot’s default logging (SLF4J + Logback).
  • Supports structured logging and all log levels (info, warn, error, debug).
  • Keeps code cleaner and easier to maintain.

Other variants available:

@Log, @Log4j, @Log4j2, @CommonsLog — but @Slf4j is the most common and recommended.


9. @UtilityClass

@UtilityClass is a hidden gem in Lombok’s toolkit.

It’s used to create utility classes — classes that only contain static methods and constants.

Lombok will automatically:

  • Make the class final.
  • Add a private constructor (preventing instantiation).
  • Convert all fields and methods to static.
import lombok.experimental.UtilityClass;

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

    public final double PI = 3.14159;
}
Enter fullscreen mode Exit fullscreen mode

Usage:

int sum = MathUtils.add(5, 10);

Why is it useful?

  • Eliminates boilerplate for utility classes.
  • Enforces correct usage (non-instantiable, static members).
  • Perfect for helpers, validators, or constants.

Without Lombok, you’d need to write:

public final class MathUtils {
    private MathUtils() {}
    public static int add(int a, int b) {
        return a + b;
    }
}
Enter fullscreen mode Exit fullscreen mode

With Lombok — one line. Clean and elegant.


10. @ToString

Generates a toString() method automatically.

import lombok.ToString;

@ToString
public class User {
    private String name;
    private int age;
}
Enter fullscreen mode Exit fullscreen mode

Exclude fields when needed:

@ToString(exclude = "password")
public class User {
    private String username;
    private String password;
}
Enter fullscreen mode Exit fullscreen mode

Why is it useful?

  • Great for debugging and logging.
  • Avoids maintenance issues when adding or renaming fields.
  • Works perfectly with @Data or on its own for better control.

Best Practices & When to Avoid Lombok

While Lombok can make your life easier, it’s not always the right tool for every situation.

  • Avoid overusing @Data It may generate methods you don’t need and cause issues in entities or complex models.
  • Prefer immutability Use @Value or makeFinal = true in @FieldDefaults when possible.
  • Mind your team’s tooling Ensure everyone’s IDE and CI/CD pipelines support annotation processing.
  • Be explicit when needed Don’t hide complexity behind annotations if it reduces clarity for new contributors.

Conclusion

Lombok is a must-have library for Java developers who value clean, maintainable, and expressive code.

It removes the friction of boilerplate, integrates seamlessly with Spring Boot, and helps you focus on what truly matters: business logic.

Key takeaways:

  • Use Lombok for faster development and cleaner classes.
  • Combine @FieldDefaults with @RequiredArgsConstructor for elegant constructor injection.
  • Use @Value for immutability and @Builder for readability.
  • Don’t overlook gems like @Slf4j and @UtilityClass.

Want more? Check out the GitHub repository for more examples and full implementations and my Pro Starter Kit on Gumroad!


💬 Join the Discussion

What do you think about Lombok? Do you love it, or do you find it hides too much magic?

Share your thoughts in the comments!

  • 👉 How has Lombok helped (or hurt) your Java projects?
  • 👉 Which annotations do you use the most?

Your feedback will help other developers (and me!) improve future articles.

Top comments (0)