File tree Expand file tree Collapse file tree 1 file changed +42
-1
lines changed Expand file tree Collapse file tree 1 file changed +42
-1
lines changed Original file line number Diff line number Diff line change @@ -840,4 +840,45 @@ public class ColorPoint {
840
840
841
841
** 一致性(` consistency ` )** --- equals 约定的第四个条件是,如果两个对象相等,它们就必须始终保持相等,除非它们中有一个对象(或两个都)被修改了。换句话说,可变对象在不同的时候可以与不同的对象相等,而不可变对象则不会这样。当你在写一个类的时候,应该仔细考虑它是否应该不可变的(见第 15 条)。如果类是不可变的,就必须保证 equals 方法满足这样的限制条件:相等的对象永远相等,不相等的对象永远不相等。
842
842
843
- 无论是否是不可变的,** 都不要使 equals 方法依赖于不可靠的资源** 。如果违反了这条禁令,要想满足一致性的要求就十分困难了。例如,java.net.URL 的 equals 方法依赖于对 URL 中主机 IP 地址的比较。将一个主机名转变成 IP 地址可能需要访问网络,随着时间的推移,不确保会产生相同的结果。这样会导致 URL 的 equals 方法违反 equals 约定,在实践中有可能引发一些问题。(遗憾的是,因为兼容性的要求,这一行为无法被改变。)除了极少数的例外情况,equals 方法都应该对驻留在内存中的对象执行确定性的计算。
843
+ 无论是否是不可变的,** 都不要使 equals 方法依赖于不可靠的资源** 。如果违反了这条禁令,要想满足一致性的要求就十分困难了。例如,java.net.URL 的 equals 方法依赖于对 URL 中主机 IP 地址的比较。将一个主机名转变成 IP 地址可能需要访问网络,随着时间的推移,不确保会产生相同的结果。这样会导致 URL 的 equals 方法违反 equals 约定,在实践中有可能引发一些问题。(遗憾的是,因为兼容性的要求,这一行为无法被改变。)除了极少数的例外情况,equals 方法都应该对驻留在内存中的对象执行确定性的计算。
844
+
845
+ ** 非空性(` Non-nullity ` )** ---最后一个要求是所有的对象都必须不等于 null。为了满足 equals 方法的这个要求,有人会使用通过一个显示的 null 测试来防止这种情况:
846
+
847
+ ``` java
848
+
849
+ @Override
850
+ public boolean equals(Object o) {
851
+ if (o == null ) {
852
+ return false ;
853
+ }
854
+ ...
855
+ }
856
+
857
+ ```
858
+
859
+ 这项测试是不需要的。为了测试其参数的等同性,equals 方法必须把参数转换成适当的类型,以便可以调用它的访问方法(` accessor ` ),或者访问它的域。在转换之前,equals 方法必须使用 instanceof 操作符,检查其参数是否为正确的类型:
860
+
861
+ ``` java
862
+
863
+ @Override
864
+ public boolean equals(Object o) {
865
+ if (! (o instanceof MyType )) {
866
+ return false ;
867
+ }
868
+ MyType mt = MyType(o);
869
+ ...
870
+ }
871
+
872
+ ```
873
+
874
+ 如果漏掉了这一步的类型检查,并且传递给 equals 方法的参数又是错误的类型,那么 equals 方法将会抛出 ClassCastException 异常,这就违反了 equals 的约定。由于 instanceof 的特性[ JLS, 15.20.2] ,第一个操作数为 null,不管第二个操作数是不是 null,都会返回 false。所以这样就不需要我们再自己手动地判断是否为空。
875
+
876
+ 结合所有这些方法,得出了以下实现高质量 equals 方法的诀窍:
877
+
878
+ 1 . ** 使用 == 操作符检查“参数是否为这个对象的引用”** 。如果是,则返回 true。这只不过是一种性能优化,如果比较操作有可能很昂贵,就值得这么做。
879
+
880
+ 2 . ** 使用 instanceof 操作符“参数是否为正确的类型”** 。
881
+
882
+ 3 . ** 把参数转换成正确的类型** 。因为转换之前进行过 instanceof 测试,所以确保会成功。
883
+
884
+ 4.
You can’t perform that action at this time.
0 commit comments