0

I'm learning Java language and I have one question for you.

For example: I have a class Employee like this:

public class Employee {

    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

So I should write method equals() like:

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return id == employee.id && Objects.equals(name, employee.name);
    }

or

    @Override
    public boolean equals(Object o) {
        if (super.equals(o)) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return id == employee.id && Objects.equals(name, employee.name);
    }

My book says:

if you redefine the equals method in a subclass, use super.equals(other).

but all classes extends Object class so which version of this method is better? I think that the first option will be faster (CPU). And the first method is the most popular, but why?

Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
  • 1
    Considering that the body of `Object::equals` is just `return (this == obj);`, calling `super.equals` instead seems pointless. – Federico klez Culloca Feb 21 '23 at 14:30
  • The default implementation of equals returns pointer equality (meaning either it's the same instance, or it's not equal). Usually equals (and hashCode together) are overridden as you show to provide functional equality, meaning for example two different instances that have the same data are considered to be equal, to then leverage such functional equality on data structures like hash tables. Of course the overriden equals is (slightly) less performant but it is functionally completely different from the pointer equality – Matteo NNZ Feb 21 '23 at 14:33
  • Does this answer your question? [Why do I need to override the equals and hashCode methods in Java?](https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java) – Matteo NNZ Feb 21 '23 at 14:34
  • And before you think about performance, think about what other coders expect. My first instinct when reading the version with the call to `super.equals` would be to double check whether the class inherits from another class, wasting *my* time rather than CPU time. – Federico klez Culloca Feb 21 '23 at 14:34
  • "if you redefine the equals method in a subclass, use super.equals(other)." This is really bad advice: equals is _hard_ to define correctly across a hierarchy of types. For example, equals needs to be symmetrical; but `parent.equals(child)` is not necessarily equal to `child.equals(parent)`, because the child equals may test additional properties that only exist on the child class. And you can't say "oh, if you're comparing a child and parent class, only consider properties of the parent class", because you then potentially invalidate transitivity. – Andy Turner Feb 21 '23 at 14:37

3 Answers3

0

By default, equals() refers to the method from Object class, however your book means that if you work with a child and a parent class which overrides the equals() method, you should use super.equals() to call the function redefined in the parent element.

Maël
  • 11
  • 4
-1

if (super.equals(o)) return true; that doesn't make much sense, just use the == version.

Note: you can test the correctness of your hashCode() - equals() implementations using the equalsverifier library.

erosb
  • 2,943
  • 15
  • 22
-1

It actually depends on the requirement. I'm elaborating.

Suppose, your requirement is to be equal with another object, parents needed to be equal as well, you should use

if (super.equals(o)) return true;

The topmost class in the inheritance tree will use

if (this == o) return true;

then. Though, if you keep the same as its child class, it will call the Object class's equals() which checks reference, so still same output with another extra calling.

Here instead of calling parent class equals() you could compare parent class fields directly in the subclass. But think that, in the future, if your business doesn't need some field from the parent class, and tells you that to remove that field from the parent class, you will need to delete it in subclasses as well. So to reduce that extra coding, better don't use the parent class field in the subclass's equals() method to compare equality.

But if the requirement is just a specific class needs to be considered to get equality, then you can use

if (this == o) return true;

without any problem.

Mukit09
  • 2,956
  • 3
  • 24
  • 44