• 三、equals重写规范


    1、基本概念

    Java的equals方法用来比较两个对象是否相等,该方法是继承自Object类,因此所有的类都可以使用该方法,但是一般类如果涉及到后面的比较的时候,都需要重写该方法,因为Object中提供的实现默认比较的是两个对象的地址。

    2、equals重写需要遵守的规则

    (1)自反性,自己和自己比较,要返回true
    (2)对称性,x和y比较的结果与y和x比较的结果应该保持一致
    (3)传递性,x和y是相等的,y和z是相等的,那么x和z是相等的
    (4)一致性,如果x和y引用对象的地址没有发生变化,那么反复调用equals应该返回一致的结果
    (5)对于任意非空引用x,x.equals(null),应该返回false

    3、equals重写模版

    public class Person {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public boolean equals(Object otherObject) {
            // 如果两个对象是一个对象,那么返回true
        	// 满足自反性
            if (this == otherObject) {
                return true;
            }
    
            // 任何一个对象和null比较,都要返回false,满足性质5
            if (otherObject == null) {
                return false;
            }
    
            // 如果两个对象本质上类型不一样,那么应该返回false
            // 为了满足对称性,这条语句保证了Person类的equals方法
            // 仅能和同为Person类型的其他类进行比较
            if (otherObject.getClass() != getClass()) {
                return false;
            }
    
            // 如果所有的子类都有相同的比较语义,那么将上面的if判断改成
            // 下面的
            /*
            if (!(otherObject instanceOf Person)) {
                return false;
            }*/
    
            // 将Object强制类型转换为Person类型
            Person other = (Person) otherObject;
            // 这里使用Objects的静态方法进行比较
            // 可以有效防止name为null,引发空指针异常的问题
            return Objects.equals(other.name,  name);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    4、equals的争议

    有的人建议将

    if (o.getClass() != getClass()) {
    	return false;
    }
    
    • 1
    • 2
    • 3

    换成

    if (!(o instanceOf Person)) {
    	return false;
    }
    
    • 1
    • 2
    • 3

    换了之后就可以让父类和子类进行比较了,但是这样造成一个麻烦:
    (1)子类没有重写父类的equals方法,该方法可以让父类和子类进行比较,但是这样将会导致无法对子类特有的部分进行比较。
    (2)子类重写了父类的equals方法,子类按照上述方法重写之后,将会丧失equals方法的对称性,父类和子类互换位置后比较结果可能不一致。

    5、关于争议的原则

    如果需要对子类特定的部分进行比较,那么不要使用instanceOf的方式,如果所有子类的比较规则都是相同的,那么可以使用instanceOf方法,然后在父类中声明该比较方法,同时将该方法声明为final类型,这样可以避免子类对该方法进行重写。equals的通用写法建议参考上述的模版写法。

    6、其他

    重写equals的时候要同时重写对象的hashCode方法,equals相等的两个对象的hashCode也要返回相同的值,这是一个必须遵守的原则。

  • 相关阅读:
    Webfunny大版本改造(mysql迁移至clickhouse)
    hdu 3549 Flow Problem(简单网络流Dinic)
    使用TinyXML-2解析XML文件
    前端架构师之路03_移动端规范兼容处理
    04、JavaWeb启程——数据库
    服务器系统和普通系统的区别
    antd5 虚拟列表原理(rc-virtual-list)
    一个超好看的音乐网站设计与实现(HTML+CSS)
    9 二叉树的重建--来源于沈钰S同学(舒姐)
    Sa-Token 一个轻量级Java权限认证框架
  • 原文地址:https://blog.csdn.net/xichengfengyulou/article/details/127659101