Core Java

Lombok Constructor Annotations Example

1. Introduction

Lombok is an open-source Java library that generates getter, setter, toString, equals, hashCode, and constructors automatically to reduce common boilerplate code. There are three constructor annotations: @AllArgsConstructor, @RequiredArgsConstructor, and @NoArgsConstructor. In this example, I will demonstrate the Lombok constructor annotations comparison between Lombok @AllArgsConstructor, @RequiredArgsConstructor, and @NoArgConstructor.

2. Setup

In this step, I will create a maven project with both Lombok and Junit libraries.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.zheng.demo</groupId>
	<artifactId>constructor-lombok</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>

		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-api</artifactId>
			<version>5.10.2</version>
			<scope>test</scope>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.32</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>
</project>

3. @NoArgsConstructor

In this step, I will create a WithNoArgsConstructor.java class which annoates with @NoArgsConstructor. The @NoArgsConstrctor generates a constructor with no parameters. If this is a final field, then you can either initialize it or with @NoArgsConstructor(force = true) to initialize with a default value (0/false/null). The @NoArgsConstructor is very useful as many frameworks require a no-args constructor.

WithNoArgsConstructor.java

package org.zheng.demo.data;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;

@Data
@NoArgsConstructor(force=true)
public class WithNoArgsConstructor {
	private final String someFinalString;
	@NonNull
	private String someNonNullString;
	private int someNumber;
	private String someString;
}

Use the Eclipse outline view, you can see the no-args constructor is created as the following screenshot.

Figure 1. No-args Constructor

4. @RequiredArgsConstructor

In this step, I will create a WithRequiredArgsConstructor.java class with the @RequiredArgsConstructor annotation. @RequiredArgsConstructor generates a constructor with parameters for each field that requires special handling with the following rules:

  • All non-initialized final fields get a parameter.
  • Any fields that are marked as @NonNull that aren’t initialized where they are declared.
  • For those fields marked with @NonNull, an explicit null check is also generated. The constructor will throw a NullPointerException if any of the parameters intended for the fields marked with @NonNull contain null.
  • The order of the parameters match the order in which the fields are declared in the class.

WithRequiredArgsConstructor.java

package org.zheng.demo.data;

import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Data
@RequiredArgsConstructor
public class WithRequiredArgsConstructor {
	@NonNull
	private String defaultNonNullString = "Mary";
	private final int initilizedFinalInt = 10;
	private final String someFinalString;
	@NonNull
	private String someNonNullString;	
	private int someNumber;
	private String someString;
}

Verified the required arguments constructor is created via the Eclipse outline view as the following screenshot.

Figure 2, Required Arguments Constructor

5. @AllArgsConstructor

In this step, I will create a WithAllContructor.java class annotated with @AllArgsConstructor. @AllArgsConstructor generates a constructor with parameters for each field in the class (except the final fields with initialization). Fields marked with @NonNull result in null checks on those parameters.

WithAllContructor.java

package org.zheng.demo.data;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;

@Data
@AllArgsConstructor
public class WithAllContructor {
	private final int initilizedFinalInt = 10;
	private final String someFinalString;
	@NonNull
	private String someNonNullString;
	private int someNumber;
	private String someString;
}

Confirmed the all arguments constructor is created via the Outline view.

Figure 3. All Arguments Constructor

6. More than One Constructors

In this step, I will create a WithMoreContructors.java class annotated with all three constructor annotations. It will generate three constructors.

WithMoreContructors.java

package org.zheng.demo.data;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class WithMoreContructors {
	private final String someFinalString="defaultFinalString";
	@NonNull
	private String someNonNullString;
	private int someNumber;
	private String someString;
}

Check the class with the outline view as the following screenshot:

Figure 4. With More Constructors

7. Juit Tests

In this step, I will create a TestLomBokConstructorjava Junit test class. It has 4 test methods.

  • test_WithAllContructor: verify the @AllArgsConstructor.
  • test_WithNoArgsConstructor: verify the @NoArgsConstructor.
  • test_WithRequiredArgsConstructor: verify the @RequiredArgsConstructor.
  • test_WithRequiredArgsConstructor_exception: verify the @RequiredArgsConstructor with null value.

TestLomBokConstructor.java

package org.zheng.demo;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import org.zheng.demo.data.WithAllContructor;
import org.zheng.demo.data.WithNoArgsConstructor;
import org.zheng.demo.data.WithRequiredArgsConstructor;

class TestLomBokConstructor {

	private static final int THIRTY = 30;
	private static final String NON_NILL = "nonNill";
	private static final String ZHENG = "Zheng";
	private static final String TEST = "test";

	@Test
	void test_WithAllContructor() {
		WithAllContructor pojo = new WithAllContructor(TEST, NON_NILL, THIRTY, ZHENG);
		
		assertEquals(THIRTY, pojo.getSomeNumber());
		assertEquals(TEST, pojo.getSomeFinalString());
		assertEquals(ZHENG, pojo.getSomeString());
		assertEquals(NON_NILL, pojo.getSomeNonNullString());

	}

	@Test
	void test_WithNoArgsConstructor() {
		WithNoArgsConstructor pojo = new WithNoArgsConstructor();
		
		pojo.setSomeNonNullString(NON_NILL);
		pojo.setSomeNumber(THIRTY);
		pojo.setSomeString(ZHENG);

		assertEquals(THIRTY, pojo.getSomeNumber());
		assertNull(pojo.getSomeFinalString());
		assertEquals(ZHENG, pojo.getSomeString());
		assertEquals(NON_NILL, pojo.getSomeNonNullString());

	}

	@Test
	void test_WithRequiredArgsConstructor() {
		WithRequiredArgsConstructor pojo = new WithRequiredArgsConstructor(ZHENG, NON_NILL);

		pojo.setSomeNumber(THIRTY);
		pojo.setSomeString(TEST);

		assertEquals(THIRTY, pojo.getSomeNumber());
		assertEquals(ZHENG, pojo.getSomeFinalString());
		assertEquals(TEST, pojo.getSomeString());
		assertEquals(NON_NILL, pojo.getSomeNonNullString());
		assertEquals(10, pojo.getInitilizedFinalInt());
		assertEquals("Mary", pojo.getDefaultNonNullString());
	}

	@Test
	void test_WithRequiredArgsConstructor_exception() {
		NullPointerException ex = assertThrows(NullPointerException.class, () -> {
			new WithRequiredArgsConstructor(ZHENG, null);
		});

		assertTrue(ex.getMessage().contains("someNonNullString is marked non-null but is null"));
	}

}

Run the Junit tests and all passed.

8. Conclusion

In this example, I showed the Lombok constructor annotations comparison. As you seen in the example, the Lombok @Data annotation includes @RequiredArgsConstructor, so it’s the best practices to annotate with @NoArgsConstructor as Java beans, POJO, Jackson, JSON, etc. require no-arguments constructor to create and manage instance. Please note that the static fields are skipped by these three constructor annotations and developers can write their own specialized constructors.

9. Download

This was an example of a maven project which included @NoArgsConstructor, @RequiredArgsConstructor, and @AllArgsConstructor.

Download
You can download the full source code of this example here: Lombok Constructor Annotations Example

Mary Zheng

Mary graduated from the Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She worked as a lead Software Engineer where she led and worked with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button