🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### [测试对象等价](https://lingcoder.gitee.io/onjava8/#/book/04-Operators?id=%e6%b5%8b%e8%af%95%e5%af%b9%e8%b1%a1%e7%ad%89%e4%bb%b7) 关系运算符`==`和`!=`同样适用于所有对象之间的比较运算,但它们比较的内容却经常困扰 Java 的初学者。下面是代码示例: ~~~ // operators/Equivalence.java public class Equivalence { public static void main(String[] args) { Integer n1 = 47; Integer n2 = 47; System.out.println(n1 == n2); System.out.println(n1 != n2); } } ~~~ 输出结果: ~~~ true false ~~~ 表达式`System.out.println(n1 == n2)`将会输出比较的结果。因为两个**Integer**对象相同,所以先输出**true**,再输出**false**。但是,尽管对象的内容一样,对象的引用却不一样。`==`和`!=`比较的是对象引用,所以输出实际上应该是先输出**false**,再输出**true**(译者注:如果你把 47 改成 128,那么打印的结果就是这样,因为 Integer 内部维护着一个 IntegerCache 的缓存,默认缓存范围是 \[-128, 127\],所以 \[-128, 127\] 之间的值用`==`和`!=`比较也能能到正确的结果,但是不推荐用关系运算符比较,具体见 JDK 中的 Integer 类源码)。 那么怎么比较两个对象的内容是否相同呢?你必须使用所有对象(不包括基本类型)中都存在的`equals()`方法,下面是如何使用`equals()`方法的示例: ~~~ // operators/EqualsMethod.java public class EqualsMethod { public static void main(String[] args) { Integer n1 = 47; Integer n2 = 47; System.out.println(n1.equals(n2)); } } ~~~ 输出结果: ~~~ true ~~~ 上例的结果看起来是我们所期望的。但其实事情并非那么简单。下面我们来创建自己的类: ~~~ // operators/EqualsMethod2.java // 默认的 equals() 方法没有比较内容 class Value { int i; } public class EqualsMethod2 { public static void main(String[] args) { Value v1 = new Value(); Value v2 = new Value(); v1.i = v2.i = 100; System.out.println(v1.equals(v2)); } } ~~~ 输出结果: ~~~ false ~~~ 上例的结果再次令人困惑:结果是**false**。原因:`equals()`的默认行为是比较对象的引用而非具体内容。因此,除非你在新类中覆写`equals()`方法,否则我们将获取不到想要的结果。不幸的是,在学习[复用](https://lingcoder.gitee.io/onjava8/#/./08-Reuse)(**Reuse**) 章节后我们才能接触到“覆写”(**Override**),并且直到[附录:集合主题](https://lingcoder.gitee.io/onjava8/#/./Appendix-Collection-Topics),才能知道定义`equals()`方法的正确方式,但是现在明白`equals()`行为方式也可能为你节省一些时间。 大多数 Java 库类通过覆写`equals()`方法比较对象的内容而不是其引用。