Effective Java 第8条的疑问
编程技术  /  houtizong 发布于 3年前   118
Symmetry—The second requirement says that any two objects must agree on
whether they are equal. Unlike the first requirement, it’s not hard to imagine vio-
lating this one unintentionally. For example, consider the following class, which
implements a case-insensitive string. The case of the string is preserved by
toString but ignored in comparisons:
// Broken - violates symmetry!
public final class CaseInsensitiveString {
private final String s;
public CaseInsensitiveString(String s) {
if (s == null)
throw new NullPointerException();
this.s = s;
}
// Broken - violates symmetry!
@Override public boolean equals(Object o) {
if (o instanceof CaseInsensitiveString)
return s.equalsIgnoreCase(
((CaseInsensitiveString) o).s);
if (o instanceof String) // One-way interoperability!
return s.equalsIgnoreCase((String) o);
return false;
}
... // Remainder omitted
}
The well-intentioned equals method in this class naively attempts to interop-
erate with ordinary strings. Let’s suppose that we have one case-insensitive string
and one ordinary one:
CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
As expected, cis.equals(s) returns true. The problem is that while the
equals method in CaseInsensitiveString knows about ordinary strings, the
equals method in String is oblivious to case-insensitive strings. Therefore
s.equals(cis) returns false, a clear violation of symmetry. Suppose you put a
case-insensitive string into a collection:
List<CaseInsensitiveString> list =
new ArrayList<CaseInsensitiveString>();
list.add(cis);
What does list.contains(s) return at this point? Who knows? In Sun’s cur-
rent implementation, it happens to return false, but that’s just an implementation
artifact. In another implementation, it could just as easily return true or throw a
runtime exception. Once you’ve violated the equals contract, you simply don’t
know how other objects will behave when confronted with your object.
To eliminate the problem, merely remove the ill-conceived attempt to interop-
erate with String from the equals method. Once you do this, you can refactor the
method to give it a single return:
@Override public boolean equals(Object o) {
return o instanceof CaseInsensitiveString &&
((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
这段话最后说改成的代码是
public final class CaseInsenstiveString {private final String s;public CaseInsenstiveString(String s) {if(s == null) {throw new NullPointerException();} this.s = s;}@Overridepublic boolean equals(Object o) {return o instanceof CaseInsenstiveString &&((CaseInsenstiveString) o).s.equalsIgnoreCase(s);}public static void main(String[] args) {CaseInsenstiveString cis = new CaseInsenstiveString("test");String s = "test";System.out.println(cis.equals(s));System.out.println(s.equals(cis));}}
测试结果,cis为Test还是test都是false
那么他这里的说法的意思是 根本不让CaseInsentiveString和String进行比较(因为o instanceof CaseInsenstiveString就是false了),即类型不同怎么比都false
还是有其他意思?
从对称性来看,是成立了,但是这样的例子怎么感觉不是说的这个意思,请大家指点
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接