【Effective Java 10.2】覆盖 equals 时请遵守通用约定 —— 对称性
2022/3/28 22:22:36
本文主要是介绍【Effective Java 10.2】覆盖 equals 时请遵守通用约定 —— 对称性,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
任何两个对象对于 “它们是否相等” 问题必须保持一致。与第一个要求不同,若无意中违反这一条,这种情形倒是不难想象。例如,下面的类,它实现了一个不区分大小写的字符串。字符串由 toString
保存,但在 equals
操作中被忽略。
/** * 覆写 Object 的 equals 方法时, 必须满足对称性要求 (Symmetry) * 即 x.equals(y) 与 y.equals(x) 的行为必须一致 * <p> * 下面展示了一个违反该约定的情况 * 一旦违反了 equals 约定, 当其他对象面对你的对象时, 你完全不知道这些对象的行为会怎样. */ public class SymmetryBadDemo { public static final class CaseInsensitiveString { private final String s; public CaseInsensitiveString(String s) { this.s = s; } /** * 这里的 equals 方法存在一个漏洞 * 就是一个 CaseInsensitiveString 对象和一个 String 对象比较的时候会出现问题 * 造成这一现象的原因主要是 */ @Override public boolean equals(Object o) { if (o instanceof CaseInsensitiveString) { return s.equalsIgnoreCase(((CaseInsensitiveString) o).s); } if (o instanceof String) { return s.equalsIgnoreCase(((String) o)); } return false; } @Override public int hashCode() { return Objects.hash(s.toLowerCase()); } } public static void main(String[] args) { CaseInsensitiveString cis = new CaseInsensitiveString("Polish"); String s = "polish"; System.out.println("违反自反性的例子"); System.out.println("cis.equals(s) = " + cis.equals(s)); System.out.println("s.equals(cis) = " + s.equals(cis)); } }
为了解决这个问题,是需要禁止 String
与 CaseInsensitiveString
之间的互操作即可。
public class SymmetryGoodDemo { public static final class CaseInsensitiveString { private final String s; public CaseInsensitiveString(String s) { this.s = s; } /** * 解决方法: 禁止与 String 类型的对象互操作 * 由于 CaseInsensitiveString 与 String 之间没有任何继承关系. * 而 equals 函数输入的是一个 Object 对象 * 要避免 CaseInsensitiveString 与 String 之间进行比较 * 就要在 equals 中主动判断 Object 对象的实际类型与当前类的类型是否一致 */ @Override public boolean equals(Object o) { return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); } @Override public int hashCode() { return Objects.hash(s.toLowerCase()); } } public static void main(String[] args) { CaseInsensitiveString cis = new CaseInsensitiveString("Polish"); String s = "polish"; System.out.println("遵守自反性的修改"); System.out.println("cis.equals(s) = " + cis.equals(s)); System.out.println("s.equals(cis) = " + s.equals(cis)); } }
这篇关于【Effective Java 10.2】覆盖 equals 时请遵守通用约定 —— 对称性的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16ShardingSphere 如何完美驾驭分布式事务与 XA 协议?
- 2024-11-16ShardingSphere如何轻松驾驭Seata柔性分布式事务?
- 2024-11-16Maven资料入门指南
- 2024-11-16Maven资料入门教程
- 2024-11-16MyBatis Plus资料:新手入门教程与实践指南
- 2024-11-16MyBatis-Plus资料入门教程:快速上手指南
- 2024-11-16Mybatis资料入门教程:新手必看指南
- 2024-11-16MyBatis资料详解:新手入门与初级实战指南
- 2024-11-16MyBatisPlus资料:初学者入门指南与实用教程
- 2024-11-16MybatisPlus资料详解:初学者入门指南