如何正确定义Java的equals()方法?两种实现该选哪一种?
我正在学习Java语言,有一个问题请教。我定义了如下Employee类:
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; } }
现在有两种equals()方法的实现方式:
第一种实现
@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); }
第二种实现
@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); }
我的书籍提到:
如果你在子类中重定义equals方法,请使用super.equals(other)
但所有类都继承自Object类,请问哪一种实现更好?我认为第一种在CPU层面更快,且它更为流行,原因是什么?
解答
首先明确核心区别:Object类的默认equals()实现就是直接比较对象引用(return this == obj;),所以第二种里的super.equals(o)和第一种里的this == o逻辑完全等价,但第一种实现确实更高效,也更符合通用写法,原因如下:
性能更优
直接写this == o是CPU层面的直接内存地址比较,省去了一次方法调用的栈操作开销——虽然单次调用的性能差异微乎其微,但在高频调用的场景下,累积的性能提升会更明显。代码更直观
this == o直接表达了「判断是否为同一个对象实例」的逻辑,阅读代码的人不需要去追溯父类(这里是Object)的equals实现,理解成本更低。符合通用规范
JDK中大部分核心类(比如String、Integer)的equals实现都是从this == o开始的,这种写法已经成为Java社区的通用规范,更易被其他开发者理解和维护。
至于书籍里提到的「子类重写equals时使用super.equals(other)」,这个建议是针对父类已经自定义重写过equals的场景——比如如果Employee有一个父类Person,而Person已经重写了equals来比较姓名、年龄等字段,那么Employee作为子类,就需要先调用super.equals(o)来验证父类层面的相等性,再比较子类自己的字段(比如id)。但你的Employee直接继承自Object,Object的equals没有自定义逻辑,所以这个建议不适用当前场景。
总结:在你的场景下,第一种实现是更优的选择,既高效又符合行业通用写法。
内容的提问来源于stack exchange,提问作者JavaStudent001

