提示十

作者: 飞絮搅青冥 | 来源:发表于2022-05-16 22:15 被阅读0次

今天来看提示十:覆盖equals时需要遵守的通用约定。

当equals没有被覆盖时,比较的是内存中的地址,类的每个实例都只和自身相等,当满足下面条件时,我们不会去覆盖equals方法:

  • 每个类的实例都是固有唯一的。
  • 不太关心类是否提供了逻辑相等的测试功能。
  • 父类已经重写了 equals 方法,则父类行为完全适合于该子类。
  • 类是私有的或包级私有的,可以确定它的 equals 方法永远不会被调用。

接下来就是重写equals时需要注意的五个原则:

  • 自反性: 对于任何非空引用 x, x.equals(x) 必须返回 true。
  • 对称性: 对于任何非空引用 x 和 y,如果且仅当 y.equals(x) 返回 true 时 x.equals(y) 必须返回 true。
  • 传递性: 对于任何非空引用 x、y、z,如果 x.equals(y) 返回 true,y.equals(z) 返回 true,则 x.equals(z) 必须返回 true。
  • 一致性: 对于任何非空引用 x 和 y,如果在 equals 比较中使用的信息没有修改,则x.equals(y) 的多次调用必须始终返回 true 或始终返回 false。
  • 非空性:对于任何非空引用 x, x.equals(null) 必须返回 false。

这五点看起来非常直接,我一开始也感觉这些都是理所应当。但是作者介绍了继承和equals的情况后我就有了不一样的想法,难怪父类重写了equals方法后,子类就不推荐重写了。

比如A类有一个属性a,重写了equals只要a相等,那么对象相同。B类继承A,并且多了一个b属性,想当然,它的equals方法就需要比较a,b两个属性。这样做的话,我们就会发现A.equals(B)没有问题,但是B.equals(A)就是false了。如果为了解决这对称性的问题,我们在B的equals方法中进行分类,如果对象是A,那么就只比较a属性,如果对象是B,那么就比较a,b属性,否则就返回false。这样做看似解决了对称性问题,但是当我们引入B1,B2两个不同的B对象,那么就容易得到B1.equals(A),A.equals(B2),但是B1和B2又显然不相同,这样又违反了传递性。所以当我们遇到这种情况时,作者推荐组合而非继承。通过组合的方式可以有效解决这个问题。

试图解决对称性会引入传递性问题

以下是编写高质量 equals 方法的配方:

  1. 使用==操作符检查参数是否为这个对象的引用, 如果是, 则返回true。
  2. 使用instanceof操作符检查参数是否为正确的类型, 如果不是, 则返回false. 注意这个地方不能使用getClass替换instanceof,这样不符合里氏替换原则。
  3. 把参数转换成正确的类型。
  4. 对于该类中的每个关键域, 检查参数中的域是否与该对象中对应的域相匹配。

现在idea等工具都提供了一键生成equals等方法,我以前也用过,但是需要注意equals的格式是可以自己选择的,有时候会生成带有getClass的方法,可能我们需要注意一下。

最后是三条提醒:

  1. 当重写 equals 方法时,同时也要重写 hashCode 方法
  2. 不要让 equals 方法试图太聪明。
  3. equal 时方法声明中,不要将参数 Object 替换成其他类型。因为这样是重载,并不是覆盖重写。应该养成良好的习惯,在覆盖方法的时候加上@Override注解,及时发现这些错误。

总之,除非必须:在很多情况下,不要重写 equals 方法,从 Object 继承的实现完全是你想要的。如果你确实重写了 equals 方法,那么一定要比较这个类的所有重要属性,并且以保护前面 equals 约定里五个规定的方式去比较。

相关文章

  • 提示十

    今天来看提示十:覆盖equals时需要遵守的通用约定。 当equals没有被覆盖时,比较的是内存中的地址,类的每个...

  • 提示9-10

    今天继续学习本书的提示9-10。还是先看提示: 提示九:对知识组合做定期投资提示十:批判性地分析你读到和听到的东西...

  • 学生习作提示十条

    1.在写人物语言时,最好不要直接写“他(她)说”,为了生动,可以在“说”字之前考虑一下加上一些修饰语。方法有四...

  • Ubuntu 系统执行 sudo 命令慢的问题

    1、 ubuntu 系统命令提示符及其前面的内容为: 每次执行 sudo 命令时都很慢,等待几十秒后提示 ...

  • 高手请进,求对

    烟锁池塘柳 提示:以火金水土木为偏旁 进古泉,喝十口白水 提示:古泉为地名,十口为古,白水为泉 日月两泉明白水 或...

  • 能把人生过的平平淡淡的,才是赢家。

    晚上十点下班的我拖着疲惫的身躯走在回家的路上,手机提示地铁末班车时间为十点十五分,并好心的提示我可能会错过。于是我...

  • 专治强迫症之PyCharm变量名有波浪线

    Pycharm的智能提示做的十分优秀,是运用非常广泛的IDE但是单词提示却不是很智能,它只能辨认英文单词是不是合法...

  • 年轻人不要怕辛苦,辛苦是人生更美好的成本 - 绿豆侠丨绿豆老师

    如果你用100度搜索“年轻人不要怕”,搜索框下面就会出现一堆关键词提示(需要开启“搜索框提示”功能),如下图: 十...

  • 厉害了,我的爹

    昏沉中听到微信的提示音,不知道是谁,懒得打开,继续昏沉。。。可是,提示音不断,连续的十几声,我知道这种情况之下,不...

  • **Markdown学习**

    教程 交易类app输入密码提示入密码提示入密码提示入密码提示入密码提示入密码提示入密码提示入密码提示入密码提示入密...

网友评论

      本文标题:提示十

      本文链接:https://www.haomeiwen.com/subject/jdnwurtx.html