第三章、对于所有对象都通用的方法
1、覆盖equals时请遵守通用约定
- 使用的场景
- 实现特殊逻辑判断就需要覆盖equals方法
- 确定equals不能被调用的类需要覆盖equals防止意外调用
约定
- 自反性,非null的 x.equals(x) 返回true
- 对称性,非null的x、y, x.equals(y)返回true,则y.equlas(x)也返回true
- 传递性,同对称性,xyz三个参数也同理
- 一致性,无论多少次调用,返回的都是同样的
- 对于非null的x,x.equals(null)返回false
非null判断,否则可能会报出NullPointerException异常
@Override public boolean equals(Object o){ if(!(o instanceof MyType)){ return false; } else { MyType mt = (MyType)o; } ... }
特殊需要注意
- double使用Double.compare,float使用Float.compare
- 其他基本类型则用==
- 对象可以递归的调用equals方法
- 数组可以使用Arrays.equals,但是数组内可能有对象为null,为了防止null异常,需要注意判断
- 其他需要注意
- 不要企图让equals方法过于智能
- equals(Object o)这里的Object不要替换为其他类型
2、覆盖equals时总要覆盖hashCode
- 总是要覆盖hashCode,才能保证有相同的hash码,不过java没有提供散列函数,书里提供了一个方法,但是不能获取最新的
@Override
public int hashCode() {
int result = 17;
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber;
return result;
}
3、始终要覆盖toString
- 对象太大的话可以使用摘要返回
4、谨慎的覆盖clone
- 谨慎
5、考虑实现Comparable接口
- 顺序的比较,可以实现自己的逻辑,不要使用要小心
第四章、类和接口
一、使类和成员的可访问性最小化
- 建议一开始都是private的,只有当另外一个类确定必须要访问的时候再放开访问权限
二、在公有类中使用访问方法而非公有域
- 例如使用get和set访问对象属性,让公有类直接暴露域从来都不是一个好的办法。
三、使可变性最小化
- 不可变类不要提供set这种能修改属性的方法,通过方法进行计算或是逻辑业务
- 如果不是必须放开访问权限,设为final最好。构造器要完全初始化好对象,不要在构造器或者静态工厂之外再提供公有的初始化方法
四、复合优先于继承
- 公认的
五、要么为继承而设计,并提供文档说明,要么就禁止继承
六、接口优于抽象类
七、类层次优于标签类
- 如果例如矩形还是圆形,通过enum来判断不如直接写2个内部类,结构清晰不乱,也没有一堆if判断5