10 Lombok Annotations Every Java Developer Should Know

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    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





    org.projectlombok
    lombok
    1.18.32
    provided






    Gradle




    compileOnly 'org.projectlombok:lombok:1.18.32'
    annotationProcessor 'org.projectlombok:lombok:1.18.32'





    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.enabl ed": 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;
    }







    At class level:






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







    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;
    }







    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();







    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;
    }







    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;
    }







    In Spring Boot, this shines with constructor injection:






    @Service
    @RequiredArgsConstructor
    public class UserService {
    private final UserRepository userRepository;
    }







    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;
    }







    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;
    }







    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;
    }






    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);







    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);
    }
    }
    }







    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;
    }






    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;
    }
    }







    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;
    }







    Exclude fields when needed:






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







    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.




    More...
Working...