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;
}
@Override
public 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
还是有其他意思?
从对称性来看,是成立了,但是这样的例子怎么感觉不是说的这个意思,请大家指点
分享到:
相关推荐
《Effective Java》第三版中文版目录 第一章 介绍 1 第二章 创建和销毁对象 4 1 考虑用静态工厂方法替换构造器 4 2 当遇到多个构造器参
effective-java.pdf
Effective Java读书笔记.pdf
Effective java 3 学习记录
effective java 读书笔记,第二版自己摘要并翻译,以备速查。
Effective Java读书笔记,记载了大部分我觉的有用的东西,前半部分有代码说明,但后半部分的代码,太过琐碎,就没有整理
【Effective Java】阅读笔记markdown 文件
《Effective Java》读书分享.pptx
15. 使类和成员的可访问性最小化 16. 在公有类中使用访问方法而非公有域 17.使可变性最小化:不可变类
effective-java 配套代码
Effective Java Effective Java Effective Java
本书以若干条建议、揸南的形式,言简意赅地介绍了J2EE开发中的微妙之处。无论你是否是Java开发人员,本书都将为你开发高效的企业系统提供诸多帮助。“通过这本书,TedNeward将帮助你实现从一个优秀的Java企业应用...
Effective Enterprise Java
effectiveJava的笔记
分享effectiveenterprisejava中文版
java四大名著之一:Effective.Enterprise.Java.中文版 高清pdf 下载
Item 85: Prefer alternatives to Java serialization Item 86: Implement Serializable with great caution Item 87: Consider using a custom serialized form Item 88: Write readObject methods defensively ...
我尽我最大的可能为大家提供了一个最佳实践 —— 《effective java》 第三版。我希望第三版继续满足需求,同时继承前两版的精神。 Small is beautiful, but simple ain’t easy 。 蓝领不是贬低的意思,主要是 ...