In this post under Lombok, I will explain with example the purpose of “doNotUseGetters” attribute of “@EqualsAndHashCode” annotation.
In a POJO class, we usually have getter method to return a formatted value of the actual value.
For example, if we have a requirement where a employee has salary information stored as decimal but if he is in India, we have to display the salary without decimal point and if in other countries then we have to display the actual value.
In those cases, the getter is modified to not return the actual value but the formatted value.
Lets take the below class as an example
Person class
public class Person {
private String firstName;
private String middleName;
private String lastName;
private float salary;
@EqualsAndHashCode.Exclude
private boolean isIndia;
public Person(String firstName, String middleName, String lastName, float salary, boolean isIndia) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.salary = salary;
this.isIndia = isIndia;
}
public float getSalary() {
return (isIndia) ? (int)this.salary : this.salary;
}
}
In the “getSalary” method, we are checking whether the value of “isIndia” field is true or false.
Consider “isIndia” field as alternative to locale object for our example.
If true we are casting a float value to int and returning it. If it is false, we are returning the orginal value.
If we annotate the class with “@EqualsAndHashCode” annotation and the field “isIndia” with “@EqualsAndHashCode.Exclude” annotation.
It generates the “equals” and “hashCode” that uses getter method of the fields (excluding “isIndia” field getter) instead of directly accessing the fields.
As a result “equals” method call on the below two Person objects will result false even though they are equal.
Person person1 = new Person("Ellis", "M", "Robertson", 1000.50f, false);
Person person2 = new Person("Ellis", "M", "Robertson", 1000.50f, true);
To avoid this problem, we use “doNotUseGetters” attribute of “@EqualsAndHashCode” annotation.
This is where “doNotUseGetters” attribute of “@EqualsAndHashCode” annotation will come into picture.
Setting “doNotUseGetters” attribute of “@EqualsAndHashCode” annotation instructs Lombok to generate “equals” and “hashCode” method by accessing the fields directly instead of indirectly through getter methods.
Below is the modified Person class.
Person class
package package16;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@EqualsAndHashCode(doNotUseGetters = true)
public class Person {
private String firstName;
private String middleName;
private String lastName;
private float salary;
@EqualsAndHashCode.Exclude
private boolean isIndia;
public Person(String firstName, String middleName, String lastName, float salary, boolean isIndia) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.salary = salary;
this.isIndia = isIndia;
}
public float getSalary() {
return (isIndia) ? (int)this.salary : this.salary;
}
}
In the above class, we have applied “@EqualsAndHashCode” annotation at class level and also set its “doNotUseGetters” to true.
Now the result of below two Person objects will be true.
Person person1 = new Person("Ellis", "M", "Robertson", 1000.50f, false);
Person person2 = new Person("Ellis", "M", "Robertson", 1000.50f, true);
Below is the main class for your reference.
Main class
package package16;
public class Example16 {
public static void main(String[] args) {
Person person1 = new Person("Ellis", "M", "Robertson", 1000.50f, false);
Person person2 = new Person("Ellis", "M", "Robertson", 1000.50f, true);
System.out.println("Salary Non Indian format: " + person1.getSalary());
System.out.println("Salary Indian format: " + person2.getSalary());
System.out.println("person1 equals person2: " + person1.equals(person2));
}
}
The output will be
Output
Salary Non Indian format: 1000.5
Salary Indian format: 1000.0
person1 equals person2: true