如何实现Java中子类实例与父类实例的equals判断返回false
实现方案
完全可以实现父类、子类实例互不相等的需求,核心是在equals方法中做严格的运行时类型校验即可。
实现逻辑
不要用instanceof做类型判断(instanceof会把子类实例判定为父类类型,导致跨类型相等的问题),改用getClass()获取实例的实际运行类型进行比对,类型不一致直接返回false。
代码示例
Person父类实现
import java.util.Objects; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; // 严格比对实际运行类型,类型不同直接返回false if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } }
Student子类实现
import java.util.Objects; public class Student extends Person { private int grade; public Student(String name, int age, int grade) { super(name, age); this.grade = grade; } @Override public boolean equals(Object o) { if (this == o) return true; // 同样做严格类型校验,仅允许同是Student类型的对象参与比对 if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; Student student = (Student) o; return grade == student.grade; } @Override public int hashCode() { return Objects.hash(super.hashCode(), grade); } }
效果说明
- 对于
Person p = new Person("John",14)和Student s = new Student("John",14,8)的场景,p.equals(s)和s.equals(p)都会直接返回false,符合跨类型不相等的需求。 - 你示例中的
Person student1 = new Student("John", 14, 8)和Student student2 = new Student("John", 14, 8),二者实际运行类型都是Student,只要字段完全匹配,equals会返回true。如果要让这种声明类型不同的场景返回false不符合equals的设计规范,也不推荐这么实现,因为equals比对的是对象实例本身的属性,和引用的声明类型无关。
注意事项
重写equals必须同步重写hashCode,保证equals返回true的两个对象hashCode一定相等,避免在HashMap、HashSet等依赖哈希的集合类中出现逻辑错误。
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

