Lombok - @Data

Let's assume you want to define a new Java class, annotate it with @RequiredArgsConstructor to generate a constructor, add the @Getter and @Setter annotations to generate getters and setters plus add the @ToString and @EqualsAndHashCode to generate the corresponding methods. That means you need to add 5 different annotations to your class definition. But wait a minute, I thought we are using Lombok to avoid writing boilerplate code so is this really the best way to achieve that?
Actually you are right, there is another way! Lombok makes this much easier by providing the @Data annotation which is a shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, @Setter on all non-final fields, and @RequiredArgsConstructor.
One great use case for @Data is generating all the boilerplate that is normally associated with simple POJOs (Plain Old Java Objects) and Java beans. Imagine how easy it is to define all those classes without the need to write biolerplate code or use IDE functionality to get this code generated.
Let's take a look at an example:
package nl.emsnsoftware.entity;
import lombok.Data;
import java.time.LocalDate;
@Data
public class Car {
String licensePlate;
String brand;
LocalDate manufacturingDate;
boolean inUse;
static int count;
}
And by runnung mvn clean install, our Car.class file looks like the following:
package nl.emsnsoftware.entity;
import java.time.LocalDate;
public class Car {
String licensePlate;
String brand;
LocalDate manufacturingDate;
boolean inUse;
static int count;
public Car() {
}
public String getLicensePlate() {
return this.licensePlate;
}
public String getBrand() {
return this.brand;
}
public LocalDate getManufacturingDate() {
return this.manufacturingDate;
}
public boolean isInUse() {
return this.inUse;
}
public void setLicensePlate(String licensePlate) {
this.licensePlate = licensePlate;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void setManufacturingDate(LocalDate manufacturingDate) {
this.manufacturingDate = manufacturingDate;
}
public void setInUse(boolean inUse) {
this.inUse = inUse;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Car)) {
return false;
} else {
Car other = (Car)o;
if (!other.canEqual(this)) {
return false;
} else if (this.isInUse() != other.isInUse()) {
return false;
} else {
label49: {
Object this$licensePlate = this.getLicensePlate();
Object other$licensePlate = other.getLicensePlate();
if (this$licensePlate == null) {
if (other$licensePlate == null) {
break label49;
}
} else if (this$licensePlate.equals(other$licensePlate)) {
break label49;
}
return false;
}
Object this$brand = this.getBrand();
Object other$brand = other.getBrand();
if (this$brand == null) {
if (other$brand != null) {
return false;
}
} else if (!this$brand.equals(other$brand)) {
return false;
}
Object this$manufacturingDate = this.getManufacturingDate();
Object other$manufacturingDate = other.getManufacturingDate();
if (this$manufacturingDate == null) {
if (other$manufacturingDate != null) {
return false;
}
} else if (!this$manufacturingDate.equals(other$manufacturingDate)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Car;
}
public int hashCode() {
int PRIME = true;
int result = 1;
int result = result * 59 + (this.isInUse() ? 79 : 97);
Object $licensePlate = this.getLicensePlate();
result = result * 59 + ($licensePlate == null ? 43 : $licensePlate.hashCode());
Object $brand = this.getBrand();
result = result * 59 + ($brand == null ? 43 : $brand.hashCode());
Object $manufacturingDate = this.getManufacturingDate();
result = result * 59 + ($manufacturingDate == null ? 43 : $manufacturingDate.hashCode());
return result;
}
public String toString() {
String var10000 = this.getLicensePlate();
return "Car(licensePlate=" + var10000 + ", brand=" + this.getBrand() + ", manufacturingDate=" + this.getManufacturingDate() + ", inUse=" + this.isInUse() + ")";
}
}
A basic comparison between the 2 files let us see that the generated classes size is much much bigger that the .java file. Now imagine the impact of applying the @Data annotation on a base code which includes not only one class but a lot more!
Thank you for reading my blog. Please make sure to check out the other Lombok annotations articles by visiting the Lombok section of my blog.