9 Basic Lombok Annotations
Java
is a verbose programming language when compared to Python
, Kotlin
. For instance, to write a POJO we might have to add accessors, mutators explicitly.
This is good if the class has less number of fields. Otherwise, adding them is simply boring, unless if someone wants to test their typing speed.
Lombok
is a library that takes the responsibility of writing boilerplate code for us thereby reducing the verbosity, and keeps the code clean and concise.
During compile time, lombok annotations adds required boilerplate code and generates bytecode. To see the effective bytecode which contains the auto-generated code by lombok, we can decompile the class file. This decompiled version of code is AKA delomboked
code.
We can delombok
the code to see the lombok auto-generated boilerplate code
java -jar lombok.jar delombok -p Book.java
Here are the basic lombok annotations and their corresponding delombok
version
-
@NoArgsConstructor
:-
Lombok
import lombok.NoArgsConstructor; @NoArgsConstructor class Book { String title; String author; }
-
Delombok
class Book { String title; String author; public Book() {} }
-
-
@AllArgsConstructor
:-
Lombok
import lombok.AllArgsConstructor; @AllArgsConstructor class Book { String title; String author; }
-
Delombok
public class Book { String title; String author; public Book(final String title, final String author) { this.title = title; this.author = author; } }
-
-
@RequiredArgsConstructor
:-
Lombok
import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class Book { final String title; String author; }
-
Delombok
public class Book { final String title; String author; public Book(final String title) { this.title = title; } }
-
Note: When there are no
final
fields then the@RequiredArgsConstructor
creates a default constructor i.e., works like@NoArgsConstructor
-
-
@Getter
-
Lombok
import lombok.Getter; @Getter public class Book { String title; String author; }
-
Delombok
public class Book { String title; String author; public String getTitle() { return this.title; } public String getAuthor() { return this.author; } }
-
-
@Setter
-
Lombok
import lombok.Setter; @Setter public class Book { String title; String author; }
-
Delombok
public class Book { String title; String author; public void setTitle(String title) { this.title = title; } public void setAuthor(String author) { this.author = author; } }
-
-
@ToString
:-
Lombok
import lombok.ToString; @ToString class Book { String title; String author; }
-
Delombok
public class Book { String title; String author; @Override public String toString() { return "Book(title=" + this.title + ", author=" + this.author + ")"; } }
-
-
@EqualsAndHashCode
:-
Lombok
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class Book { String title; String author; }
-
Delombok
public class Book { String title; String author; @Override public boolean equals(final java.lang.Object o) { if (o == this) return true; if (!(o instanceof Book)) return false; final Book other = (Book) o; if (!other.canEqual((java.lang.Object) this)) return false; final java.lang.Object this$title = this.title; final java.lang.Object other$title = other.title; if (this$title == null ? other$title != null : !this$title.equals(other$title)) return false; final java.lang.Object this$author = this.author; final java.lang.Object other$author = other.author; if (this$author == null ? other$author != null : !this$author.equals(other$author)) return false; return true; } protected boolean canEqual(final java.lang.Object other) { return other instanceof Book; } @Override public int hashCode() { final int PRIME = 59; int result = 1; final java.lang.Object $title = this.title; result = result * PRIME + ($title == null ? 43 : $title.hashCode()); final java.lang.Object $author = this.author; result = result * PRIME + ($author == null ? 43 : $author.hashCode()); return result; } }
-
-
@Data
: Bundles all the features of@RequiredArgsConstructor
,@Getter
,@Setter
,@EqualsAndHashCode
, and@ToString
together-
Lombok
-
import lombok.Data; @Data public class Book { final String id; String title; String author; }
-
-
Delombok
public class Book { final String id; String title; String author; public Book(final String id) { this.id = id; } public String getId() { return this.id; } public String getTitle() { return this.title; } public String getAuthor() { return this.author; } public void setTitle(final String title) { this.title = title; } public void setAuthor(final String author) { this.author = author; } @java.lang.Override public boolean equals(final java.lang.Object o) { if (o == this) return true; if (!(o instanceof Book)) return false; final Book other = (Book) o; if (!other.canEqual((java.lang.Object) this)) return false; final java.lang.Object this$id = this.getId(); final java.lang.Object other$id = other.getId(); if (this$id == null ? other$id != null : !this$id.equals(other$id)) return false; final java.lang.Object this$title = this.getTitle(); final java.lang.Object other$title = other.getTitle(); if (this$title == null ? other$title != null : !this$title.equals(other$title)) return false; final java.lang.Object this$author = this.getAuthor(); final java.lang.Object other$author = other.getAuthor(); if (this$author == null ? other$author != null : !this$author.equals(other$author)) return false; return true; } protected boolean canEqual(final java.lang.Object other) { return other instanceof Book; } @java.lang.Override public int hashCode() { final int PRIME = 59; int result = 1; final java.lang.Object $id = this.getId(); result = result * PRIME + ($id == null ? 43 : $id.hashCode()); final java.lang.Object $title = this.getTitle(); result = result * PRIME + ($title == null ? 43 : $title.hashCode()); final java.lang.Object $author = this.getAuthor(); result = result * PRIME + ($author == null ? 43 : $author.hashCode()); return result; } @java.lang.Override public java.lang.String toString() { return "Book(id=" + this.getId() + ", title=" + this.getTitle() + ", author=" + this.getAuthor() + ")"; } }
-
-
@Builder
-
Lombok
import lombok.Builder; @Builder public class Book { String title; String author; }
-
Delombok
public class Book { String title; String author; Book(final String title, final String author) { this.title = title; this.author = author; } public static class BookBuilder { private String title; private String author; BookBuilder() {} /** * @return {@code this}. */ public Book.BookBuilder title(final String title) { this.title = title; return this; } /** * @return {@code this}. */ public Book.BookBuilder author(final String author) { this.author = author; return this; } public Book build() { return new Book(this.title, this.author); } @java.lang.Override public java.lang.String toString() { return "Book.BookBuilder(title=" + this.title + ", author=" + this.author + ")"; } } public static Book.BookBuilder builder() { return new Book.BookBuilder(); } }
-
Lombok provides other annotations besides the aforementioned. Usage of annotation processors like Lombok is a developer’s preference. Excessive usage of these annotations makes code unreadable as it does a lot of magic under the hood through auto-generated code.
In summary
@NoArgsConstructor
- Creates a default constructor@RequiredArgsConstructor
- Creates constructor with final fields as params, otherwise if a class has no final field at all, then it behaves like@NoArgsConstructor
@Data
- Combination of@RequiredArgsConstructor
+@Setter
+@Getter
+@EqualsAndHashCode
+@ToString
@AllArgsContructor
- Creates constructor with all fields in a class, whether they are final or not.@Builder
- Creates@AllArgsConstructor
+ builder pattern
Bad-combinations
@Builder + @NoArgsConstructor
= Results in compilation error as they are contradicting@AllArgsContructor(With final fields) + @NoArgsConstructor
= results in compilation issue as final field has to be initialized
References: