Java Lombok | Automatically Generating Constructors - @NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor

Learn how to use three annotations that automatically generate constructors and what to watch out for.

Automatically Generating Constructors

There are three annotations that automatically generate constructors.

  • @NoArgsConstructor: Automatically generates a constructor with no arguments.
  • @RequiredArgsConstructor: Automatically generates a constructor with only fields declared as final as arguments.
  • @AllArgsConstructor: Automatically generates a constructor with all fields as arguments.

Using @NoArgsConstructor

You can declare the @NoArgsConstructor annotation to generate a constructor with no arguments.

package com.devkuma.tutorial.lombok;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class NoArgsConstructorTutorial {

    public NoArgsConstructorTutorial(String string) {
    }

    public static void main(String[] args) {
        new NoArgsConstructorTutorial();
    }
}

Using @RequiredArgsConstructor

You can declare the @RequiredArgsConstructor annotation to automatically generate a constructor that takes only fields declared as final as arguments.

package com.devkuma.tutorial.lombok;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class RequiredArgsConstructorTutorial {
    private String optional;
    private final int required;

    public static void main(String[] args) {
        new RequiredArgsConstructorTutorial(1);
    }
}

Using @AllArgsConstructor

You can declare the @AllArgsConstructor annotation to automatically generate a constructor that takes all fields as arguments.

package com.devkuma.tutorial.lombok;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class AllArgsConstructorTutorial {
    private String string;
    private int number;

    public static void main(String[] args) {
        new AllArgsConstructorTutorial("devkuma", 999);
    }
}

Defining a static Factory Method

By specifying the staticName attribute on each annotation, you can automatically generate a static factory method.

package com.devkuma.tutorial.lombok;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor(staticName="of")
public class StaticFactoryOfTututorial {

    private final String required;
    private int optional;

    public static void main(String[] args) {
        StaticFactoryOfTututorial tututorial = StaticFactoryOfTututorial.of("devkuma");
    }
}

Notes on Usage

@AllArgsConstructor and @RequiredArgsConstructor are very convenient for generating constructors, but using them without thought can lead to serious bugs.

Problem Code

The example below declares @AllArgsConstructor so that the x and y arguments are automatically generated in order.

package com.devkuma.tutorial.lombok.warning;

import lombok.AllArgsConstructor;
import lombok.ToString;

@AllArgsConstructor
@ToString
public class ConstructorWarning {
    private String x;
    private String y;

    public static void main(String[] args) {
        ConstructorWarning warning = new ConstructorWarning("x", "y");
        System.out.println(warning);
    }
}

Execution result:

ConstructorWarning(x=x, y=y)

The Problem

At this point, if you reorganize the code and change the order of the x and y arguments as follows, the values of the two arguments are swapped.

    private String y;
    private String x;

Execution result:

ConstructorWarning(x=y, y=x)

No error occurs, and the bug can slip in without the developer noticing it.

Solution

You can solve this problem by using the @Builder annotation.

package com.devkuma.tutorial.lombok.warning;

import lombok.Builder;

@Builder
public class ConstructorSolve {
    private String x;
    private String y;

    public static void main(String[] args) {
        ConstructorSolve warning = ConstructorSolve.builder()
                                                   .x("x")
                                                   .y("y")
                                                   .build();
        System.out.println(warning);
    }
}

With this style, even if the order of the x and y fields changes, the values of the two arguments will not be swapped.

References