第3章 对于所有对象都通用的方法
Object类 主要是为了扩展。所有非final方法都有通用的约定(它们被设计成是要被override)
*** 第8条:覆盖equals时请遵守通用约定 ***
equals方法实现了等价关系:
自反性,对称性,传递性,一致性,非null的引用值x,x.equals(null)必须是false
里氏替换原则:一个类型的任何重要属性将适用于他的子类型,因此为该类型编写的任何方法,在它的子类型上也应同样运行得很好。
权宜之计:复合代替基础
public class ColorPoint{
private final Point point ;
private final Color color ;
public ColorPoint(int x , int y ,Color color){
if(color == null)
throw new NullPointerException();
point = new Point(x,y);
this.color = color ;
}
public Point asPoint(){
return point ;
}
@Override
public boolean equals(Object o ){
if(!(o instanceof ColorPoint))
return false;
ColorPoint cp = (ColorPoint) o ;
return cp.point.equals(point) && cp.color.equals(color);
}
… …
}
考虑可变与不可变:相等的对象永远相等,不相等的对象永远不相等。
不要使equals方法依赖于不可靠的资源。
实现高质量equals方法的诀窍:
1.使用== 检查“参数是否为这个对象的引用”
2.instanceof 检查是否是正确类型
3.把参数转换成正确的类型
4.对于关键域,检查参数的域与该对象中对应的域是否相匹配
Float.compare() Double.compare() Arrays.equals()
5.覆盖equals时总要覆盖hashCode;不要企图让equals过于只能;不要将equals声明中的Object对象替换为其他的类型。
*** 第9条:覆盖equals时总要覆盖hashCode ***
相等的对象必须有相等的hash code.
一个好的散列函数通常倾向于“为不相等的对象产生不相等的散列码”
不要试图从散列码计算中排除掉一个对象的关键部分来提高性能。
*** 第10条:始终要覆盖toString ***
Object提供了toString()的一个实现:类名称@散列码的无符号十六进制
实际应用中,toString()应返回对象中包含所有值得关注的信息。
无论你是否决定指定格式,都应该在文档中说明。
*** 第11条:谨慎地覆盖clone ***
对于Cloneable接口,它改变了超类中受保护的方法的行为。
无需调用构造器就可以创建对象。
如果你覆盖了非final类中的clone方法,则应该返回一个通过调用super.clone而得到的对象
从1.5引入了协变返回类型作为泛型。
确保它不会伤害到原始的对象,并确保正确地创建克隆对象中的约束条件。
另一个实现对象拷贝的好办法是提供一个拷贝构造器活拷贝工厂。
最好不用。
*** 第12条:考虑实现Comparable接口 ***
compareTo是Comparable接口种唯一的方法
java平台类库中所有值类都实现了Comparable接口 。
sgn(表达式) :-1 0 1
顺序:从最关键域逐步进行到所有重要的域,