您的位置:首页 > Web前端

Effective Java 03 对于所有对象都通用的方法

2016-08-25 20:51 387 查看

覆盖equals时请遵守通用约定

自反性。对于任何非null的引用值x,x.equals(x)必须返回true

对称性。对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。

public final class CaseInsensitiveString {
private final String s;

public CaseInsensitiveString(String s){
if(s == null){
throw new NullPointerException();
}
this.s = s;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof CaseInsensitiveString){
return s.equalsIgnoreCase(((CaseInsensitiveString)obj).s);
}
if(obj instanceof String){
return s.equalsIgnoreCase((String)obj);
}
return false;
}

public static void main(String[] args) {
CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
System.out.println(cis.equals(s));//true
System.out.println(s.equals(cis));//false
}
}


String类中的equals方法不知道不区分大小写的字符串,显然违反了对称性。优化:

@Override
public boolean equals(Object obj) {
return obj instanceof CaseInsensitiveString && (((CaseInsensitiveString)obj).s).equalsIgnoreCase(s);
}


传递性。对于任何非null的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals也必须返回true。

一致性。对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致地返回false。

非空性。对于任何非null的引用值x,x.equals(null)必须返回false。

得出实现高质量equals方法的诀窍:

使用==操作符检查“参数是否为这个对象的引用”

使用instanceof操作符检查“参数是否为正确的类型”

把参数转换成正确的类型。因为转换之前进行过instanceof测试,所以确保会成功。

对于该类中的每个“关键”域,检查参数中的域是否与该对象中对应的域xiang相匹配。

覆盖equals是总要覆盖hashcode

在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对同一个对象调用多次,hashcode方法都必须始终如一地fan'hui返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。

如果两个对象根据equals方法比较是相等的,那么调用这两个对象中任意一个对象的hashcode方法都必须产生同样的整数结果。

如果两个对象根据equals方法比较是不相等的,那么调用者两个对象中任意一个对象的hashcode方法,则不一定要产生不同的整数结果。

始终要覆盖toString

可以使类用起来更加舒适

应该返回对象中包含的所有值得关注的信息

谨慎覆盖clone

不建议使用clone

如果覆盖了非final类中的clone方法,则应该返回一个通过调用super.clone而得到的对象

clone架构与引用可变对象的final域的正常用法是不相兼容的

如果对象中包含的域引用了可变的对象,那clone是需要单独对该对象再一次clone

所有实现了Cloneable接口的类都应该用一个公有的方法覆盖clone。此公有方法首先调用super.clone,然后修正任何需要修正的域。一般情况下,这意味着要拷贝任何包含内部“深层结构”的可变对象,并用指向新对象的引用代替原来指向这些对象的引用。虽然这些内部拷贝操作往往可以通过递归地调用clone来完成,但这通常并不是最佳方法。如果该类只包含基本类型的域,或者指向不可变对象的引用,那么多半的情况是没有域需要修正。

考虑实现Comparable接口

compareTo方法没有在Object中声明。它是Comparable接口中唯一的方法。compareTo方法不但允许简单的等同性比较,而且允许指向顺序比较,除此之外,它与Object的equals方法具有相似的特征,它还是个泛型。类实现了Comparable接口,就表明它的实例具有内在的排序关系。

如果你正在编写一个值类,它具有非常明显的内在排序关系,比如字母顺序、按数值顺序或者按年代顺序,就应该坚决考虑实现这个接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: