【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-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)