Effective Java学习笔记(三)

来源:互联网 发布:中医网络问诊单模版 编辑:程序博客网 时间:2024/05/18 12:02
第2章      所有对象通用的方法(Methods common to all objects
1           重载equals时遵守通常的合约(Obey general contract when override equals
不需要重载equals的情况:
1)  类的每个实例本来就是唯一的。采用Object的equals就可以了。
2)  不在意类是否提供一个逻辑相等的测试。
3)  超类已经重载了equals,继承自超类的行为对本类也是适合的。
4)  类是私有或是包私有的,并且你确信equals方法不会被调用。这个时候最好重载equals,然后抛出UnsupportedOperationException。
equals方法的合约:自反性,对称性,传递性,一致性。
面向对象语言中等价关系的一个基本问题。没有简单的方法可以扩展一个可实例化的类并添加一个方面,而在这同时保持equals的合约。但是对于一个抽象类,是可以的。
所有对象必须不等于null。
在equals方法中不需要进行非空检查,只需要使用instanceof操作符进行类型检查。
高质量的equals方法的建议:
1)  使用==操作符来检查作为参数的引用是否是该对象本身。如果是,则返回true。
2)  使用instanceof操作符检查参数是否是合法的类型。如果不是,返回false。
3)  把参数转换成合适的类型。
4)  对于每个显著的域,检查是否与参数中对象对应的域一致。
5)  当写完equals方法之后,问自己它是否满足对称性,传递性和一致性。
下面是一些提醒:
1)  当重载equals是总是重载hashCode。
2)  不要过分聪明。
3)  不要编写依靠不可靠资源的equals方法。比如java.net.URL类的equals方法依赖于主机的IP地址,而把主机名转换成IP地址需要访问网络,并且不是每次调用都会产生相同的结果。
4)  在equals的声明中不要把Object替换成其它类型。
 
2           当重载equals时总是重载hashCode(Always override hashCode when you override equals
当你没有重载hashCode的时候就违反了hashCode的合约:相等的对象有相等的hash code。
计算hashCode的时候把没有在相等性比较中出现的域排除在外。
如果类是不变的并且计算hash code的代码较高,可以考虑把hash code缓存起来,而不是每次都计算。
不要为了提高性能,而把对象中显著的部分从hash code的计算中移除。
 
3           总是重载toString(Always override toString
提供一个好的toString实现可以使得你的类更容易被使用。
在实践中,toString方法应该返回对象中包含的所有有意义的信息。
对于value class来说,最好在文档中记录toString返回的字符串的格式。如果你指明这种格式的话,最好提供一个以String作为参数的构造函数,这样程序员就可以方便的在对象及其字符串表示形式之间自由转换。
不管是否决定在文档中记录该格式,都应该清楚的标明你的意图。
不管是否指明该格式,都应该提供访问包含在toString返回值中值的相关信息的方法。
 
4           谨慎的重载clone(Override clone judiciously
如果类实现了Clonable接口,则Object的clone方法返回该对象的逐域的拷贝;否则就抛出CloneNotSupportedException。
实际上,clone方法的功能相当于一个构造函数。你必须确保它不会对原始对象造成损害,并且保证不变性。
所有实现Clonable接口的类都应该重载clone方法。这个公共方法首先调用super.clone,然后修正域。通常说来,这需要拷贝构成对象内部深层次结构的可变对象,并把对这些对象的引用换成对拷贝的引用。
如果一个可扩展的类,尤其是设计用来被继承的类,重载了clone方法,则该方法应该包含抛出CloneNotSupportedException在其声明中。
对象拷贝的一个好的方法是使用拷贝构造函数。
拷贝构造函数可以接收该类所实现的接口作为参数。
 
5           考虑实现Comparable(Consider implementing Comparable
通过实现Comparable接口,一个类表明它的实例拥有natural ordering。
没有简单的方法可以在扩展一个可实例化类并添加新的方面的同时保持compareTo的合约。
一个类如果其compareTo方法与equals方法不一致(即(x.compareTo(y)==0)!=(x.equals(y))),以该类的对象作为元素的排序的集合可能不会遵守集合接口的合约。
如果参数类型不正确,compareTo方法应该抛出ClassCastException;如果参数为空,compareTo方法应该抛出NullPointerException。
原创粉丝点击