Using @EqualsAndHashCode callSuper attribute

In this post under Lombok I will explain the purpose and how to use the “@EqualsAndHashCode” annotation’s “callSuper” attribute.

In my previous post under “Using @EqualsAndHashCode annotation”, I explained with example the purpose of that annotation.

Just for recap when this annotation is applied at class level it will automatically generates “equals” and “hashCode” methods for a POJO class.

But not all POJO classes are standalone, they extend other POJO classes. So at that time what will be default behavior of “@EqualsAndHashCode” annotation.

For example lets take the below class hierarchy.

Parent class

package package14;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@EqualsAndHashCode
public class TwoDShape {
    private int x, y;

    public TwoDShape(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

In the above class “TwoDShape”, I have added “EqualsAndHashCode” annotation at the class level. As a result it will generate “equals” and “hashCode” considering
all the fields which in this case is “x”, and “y”.

Now lets see the subclass

Sub class

package package14;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@EqualsAndHashCode
public class ThreeDShape extends TwoDShape {
    private int z;

    public ThreeDShape(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}

In the above subclass “ThreeDShape”, I have also added “EqualsAndHashCode” annotation at class level. As a result it will generate “equals” and “hashCode” considering
all the fields which in this case is only “z”.

But wait a second, “ThreeDShape” is not just made up of “z”, it is made up of “x”, “y”, and “z”.

So when we are comparing two “ThreeDShape” objects, the “equals” and “hashCode” method must consider all the three fields “x”, “y”, and “z”.

But the current “equals” is not doing that.

We have to change the subclass “equals” method to call super class (i.e., TwoDShape) equals method also when doing comparison.

That is where “callSuper” attribute comes into picture.

If we set this attribute to “true”, the super class “equals” method is also called in the subclass “equals” method and all the three fields “x”, “y”, and “z” will
be considered when comparing two objects.

So we have to modify the subclass code as shown below

Modified subclass

package package14;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
public class ThreeDShape extends TwoDShape {
    private int z;

    public ThreeDShape(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}

In the modified code, as you see we have set the “callSuper” attribute to true.

The same logic applies to “hashCode” methods.

In this way we have to use the “callSuper” attribute of “@EqualsAndHashCode” annotation.

Below is the main method for your reference.

Main class

package package14;

public class Example14 {
    public static void main(String[] args) {
        ThreeDShape threeDShape1 = new ThreeDShape(5, 10, 15);
        ThreeDShape threeDShape2 = new ThreeDShape(5, 10, 15);

        System.out.println("threeDShape1 equals threeDShape2: " + threeDShape1.equals(threeDShape2));
    }
}

If we execute the above main class the output will be as shown below

Output

threeDShape1 equals threeDShape2: true

Leave a Reply