@AllArgsConstructor

How To Use @AllArgsConstructor Annotation With Project Lombok In Java Applications

@AllArgsConstructor annotation automatically generates a constructor with a parameter for each field in your class.

Though this isn't entirely true as we'll see later on. i.e for the case of final fields already initialized with a value.

# Dev Environment:

  • Apache maven (v3.6.1)
  • maven-compiler-plugin (v3.8.1)
  • lombok (v1.18.8)
  • Apache Netbeans (v10.0)

TIP: For those who would like to follow along with this blog, just clone my repository git clone https://github.com/steven7mwesigwa/java-tutorials.git and navigate to java-tutorials\project-lombok\allargsconstructor. In there, you should be able to play around with all the source code used in this blog post.

# Demonstration : (Without Lombok)

Let's create a Person class that will have a manual implementation having an "all args constructor" equivalent.



public class Person {

    private String firstname;
    private String lastname;

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

}

Using @AllArgsConstructor annotation, lombok will generate this constructor for us.

# Demonstration : (With Lombok)

Let's create a Person class but this time making use of @AllArgsConstructor annotation... Full code here


//demo1			
package com.stevenmwesigwa.allargsconstructor.demo1;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Person {

    private String firstname;
    private String lastname;

    // toString() here
}

When we create and run an App.java class that makes use of this Person class Full code here, we successfully return the same string representation of our Person object as before. i.e Person{firstname=Steven, lastname=Mwesigwa}

As you can see, we didn't have to write our own constructor. Adding this annotation on top of our class declaration is enough for lombok to generate it for us.

# Case 2: @AllArgsConstructor annotation on a class having a final field already initialized with a value

You should keep in mind that if a class has a final field already initialized with a value, this field won't have a respective parameter in the constructor generated by lombok.

Let's create a Person class to demonstrate this behaviour. Full code here


//demo2			
package com.stevenmwesigwa.allargsconstructor.demo2;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Person {

    private String firstname;
    private String lastname;
    private final int numberOfLegs = 2;  // 'final' field already initialized with a value

    //toString() here

}

For the case above, lombok will generate a constructor similar to the one below.

		
...

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
		
...		

As you can see, our already initialized final field isn't part of the generated constructor.

# Case 3: @AllArgsConstructor annotation on a class having a non initialized final field

If the final field isn't initialized in a class, the constructor generated by lombok will have a respective parameter for that field.

Let's create a Person class to demonstrate this. Full code here


//demo3			
package com.stevenmwesigwa.allargsconstructor.demo3;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Person {

    private String firstname;
    private String lastname;
    private final String ssn;  // Our non initialized 'final' field

    // toString() here

}

For the case above, lombok will generate a constructor similar to the one below.

		
...

    public Person(String firstname, String lastname, String ssn) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.ssn = ssn;				
    }
		
...		

As you can see, our non initialized final field is now part of the generated constructor.

When we create and run an App.java class that makes use of this Person class Full code here, you should be able to play around with this comcept.

# Case 4: Make Lombok generate a private constructor and a public static factory method

There're cases when you don't want your client to have direct access to call your constructor.

For a case like this, You normally want to make the constructor private and provide a public static factory method wrapper to the client so that they're still able to set field values.

This can be achieved with @AllArgsConstructor(staticName="of") annotation.

NOTE: You're free to provide your own "staticName", though alot of developers prefer to use "of".

Let's create a Person class to demonstrate this. Full code here


//demo4		
package com.stevenmwesigwa.allargsconstructor.demo4;

import lombok.AllArgsConstructor;

@AllArgsConstructor(staticName = "of")
public class Person {

    private String firstname;
    private String lastname;
    private final String ssn;

    // toString() here

}

For the case above, lombok will generate a "private constructor" and a "public static factory method" similar to the one below:-

		
...

    private Person(String firstname, String lastname, String ssn) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.ssn = ssn;
    }

    public static Person of(String firstname, String lastname, String ssn) {
        return new Person(firstname, lastname, ssn);
    }
		
...		

With the set up above, the client can easily set field values like this Person.of("Steven", "Mwesigwa", "123-45-6789")

When we create and run an App.java class that makes use of this Person class Full code here, we successfully return a string representation of our Person object. i.e Person{firstname=Steven, lastname=Mwesigwa, ssn=123-45-6789}

# Case 5: Defining Multiple Constructors while using @AllArgsConstructor annotation

Well, i have good news for you. We call explicitly define other multiple custom constructors in conjuction with @AllArgsConstructor annotation.

This allows more flexibility in the sense that you're able to make some fields required or not.

We'll have a practical demo of this concept to throw more light.

Let's create a Person class to demonstrate this option. Full code here


//demo5			
package com.stevenmwesigwa.allargsconstructor.demo5;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Person {

    private String firstname;
    private String lastname;
    private String ssn;

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    // toString() here

}

As you can see above, Lombok is automatically generating an "all arg constructor" that requires the client to provide a value for all object fields. i.e firstname, lastname, ssn

In addition, we're also explicitly defining our own custom constructor where by a client is able to only provide a value for firstname and lastname.

If you're still confused, Just know that in Java we're able to define multiple constructors as long as they have different number and type of arguments for the same class.

If we were to manually type our constructors for this class, they would look similar to the snippet below :-

		
...

    public Person(String firstname, String lastname, String ssn) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.ssn = ssn;
    }

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
		
...		

When we create and run an App.java class that makes use of this Person class Full code here, you should be able to play around with this concept.

# Case 6: How To Set The Access Level For The Constructor Generated By @AllArgsConstructor annotation

You're not limited to just generating an "all arg constructor" using @AllArgsConstructor annotation.

We can also specify the access level for the generated constructor using @AllArgsConstructor(access = AccessLevel.PRIVATE).

NOTE: Keep in mind that you're free to opt for other access levels by changing the value of the access configuration key depending on your use case. i.e AccessLevel.PRIVATE, AccessLevel.PROTECTED, AccessLevel.PUBLIC.

Let's create a Person class to demonstrate this option. Full code here


//demo6			
package com.stevenmwesigwa.allargsconstructor.demo6;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Person {

    private String firstname;
    private String lastname;

    // toString() here

}

As you can see above, Lombok is automatically generating an "all arg constructor" with protected access level.

When we create and run an App.java class that makes use of this Person class Full code here, you should be able to play around with this option.

If you're not familiar with access control in Java, check out access level modifiers.

To be honest with you, this was really a long one. But am glad i was able to explore most options and share them with you here.

If anything is unclear or you wish to make any corrections, don't hesitate to leave a comment. Your feedback is greatly appreciated.

Sharing is caring. Share this blog to help out others getting started with 'project lombok' library for Java applications.

About The Author   

Steven Mwesigwa

Software Engineer at Vogue Book Consultancy Services Ltd


Picture Of Steven Mwesigwa

Steve is currently a software developer at Vogue Book Consultancy Services Ltd and a technology author. He holds a Dip. in civil engineering from Kyambogo University. He founded and maintains stevenmwesigwa.com a website that receives more than 1.5 thousand visits per month. Steve can be reached on Twitter at @steven7mwwesigwa