How To Use @FieldDefaults Annotation With Project Lombok in Java Applications

@FieldDefaults annotation enables you to avoid having to manually write access modifiers for your object fields or an enum.

NOTE: At the time of writing this blog, this was still an experimental feature.

# 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\fielddefaults. In there, you should be able to play around with all the source code used in this blog post.

# Demonstration : (Without Lombok)

Let's try this with a practical example to get the gist of it.

Let's create a Person class that will have a manual implementation of adding access modifiers to object fields. Full code here


//demo1			
package com.stevenmwesigwa.fielddefaults.demo1;

public class Person {

    private String firstname;
    private String lastname;

    // Constructor here

    // toString() here

}

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}

As you would notice, we normally add an access modifier i.e (private, public, protected) while declaring fields in our classes.

With lombok, We can use a single line of code to define an access modifier for each of our object fields.

# Demonstration : (With Lombok)

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


//demo2			
package com.stevenmwesigwa.fielddefaults.demo2;

import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class Person {

    String firstname;  // Note that we don't have an access modifier explictly defined here.
    String lastname;

    // Constructor here

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

Here, we define an access modifier by adding a level configuration key to our annotation.

The level configuration key can take on a value indicating the accessibility level i.e AccessLevel.PRIVATE, AccessLevel.PUBLIC, AccessLevel.PROTECTED.

For the case of our example above, lombok basically automatically adds a private access modifier to ALL fields that don't already have a modifier defined.i.e

  • private String firstname
  • private String lastname

What i mean by that is, incase a field already has say a private access modifier already defined, if you annotate that field with say @FieldDefaults(level = AccessLevel.PUBLIC), the field will still remain private.

What you simply have to understand is that the more explicit access modifier implementation (fields that already have an access modifier) takes precedence over the one defined through lombok annotation.

# How to make use of @FieldDefaults(makeFinal=true) and @FieldDefaults(level=AccessLevel.PRIVATE)

Besides adding an access modifier to your object fields, @FieldDefaults annotation can also be used to state if your fields will be final or not. i.e @FieldDefaults(makeFinal=true)

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


//demo3
package com.stevenmwesigwa.fielddefaults.demo3;

import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal=true)
public class Person {

    String firstname;
    String lastname;
		
    // Constructor here
    // toString() here

}

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal=true) annotation simply automatically makes your fields private final.i.e

  • private final String firstname
  • private final String lastname

# How to use @NonFinal

Now, i know some of you are wondering, if you make use of @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal=true) annotation, how do you make some fields not to be final?

Well, i would answer you by saying that, this is what @NonFinal annotation is for.

You simply prepend it on any nonfinal field in your class.

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


//demo4
package com.stevenmwesigwa.fielddefaults.demo4;

import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import lombok.experimental.NonFinal;

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class Person {

    String firstname;
    String lastname;
    @NonFinal
    String email;
		
    // Constructor here
    // toString() here

}

@NonFinal annotation on email field makes it nonfinal.

With fields in above snippet of code, lombok implicity generates for us the field declarations below. i.e

  • private final String firstname
  • private final String lastname
  • private String email

I hope this makes things clearer for you while using lombok specific annotations.

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