标签:
equals和==的异同:
1. equals和“==”都是用于对象的比较,检查两个对象的相等性;
2. “==”是操作符,因为在Java中操作符不能被重载,所以“==”的行为对每个对象来说都是相同的,而equals是方法,可以根据业务规则的不同进行重写;
3. “==”是基于对象的内存引用来进行比较的,如果两个对象的引用完全相同,即指向同一个对象,则为true;
注意:
1. 对于既不是float也不是double类型的基本类型域,可以使用“==”操作符进行比较;对于对象引用域,可以递归调用equals方法;对于float或double域,可以使用Float/Double的compare方法(因为存在Float.NaN和-0.0f以及类似的double常量,所以特殊处理);对于数组则要把做上述原则应用到每个元素上。
2. 无论什么时候重写了equals方法,必须重写hashCode方法;如果在覆盖equals后没有覆盖hashCode,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合(Hashtable,HashMap,HashSet)一起工作。
3. 如果一个类是不可变的,并且计算散列码的开销较大,就可以考虑把散列码缓存在对象内部,而不是每次请求的时候都重新计算散列码;如果你觉得这种类型的大多数对象会被用作散列键,就应该在创建实例的时候计算散列码,否则,可以选择“延迟初始化”直到hashCode第一次被调用时才初始化。
重写equals:
1. 使用==操作符检查“参数是否为这个对象的引用”;
2. 使用instanceof检查“参数是否为正确地类型”;
3. 把参数转换成正确地类型;
4.对于该类中的每个关键域,检查参数中的域是否与该对象中对应的域相匹配;
5. 覆盖equals时总要覆盖hashcode;
6. 不要企图让equals方法过于智能;
7. 不要将equals声明中的Object对象替换为其他的类型;
以下代码片段:
Object s1 = "Hello"; Object s2 = "Hello"; if (s1 == s2) { System.out.println("s1 and s2 are =="); } else if (s1.equals(s2)) { System.out.println("s1 and s2 are equals()"); } //输出为“s1 and s2 are ==”
为什么会输出“s1 and s2 are ==”?事实上,这个例子比较特殊,是一个典型的flyweight 模式在字符串对象创建中的应用,这个模式通过减少对象的创建来节约内存。String对象会创建一个字符串池,如果当前准备新创建的字符串对象的值在这个池子中已经存在,那么就不会生成新对象,而是复用池中已有的字符串对象。flyweight 模式的精髓就是对象复用。不过,只有采用Object s = “Hello”方式(而非用”new“关键字)声明String对象的时候这个规则才会被应用。
标签:
原文地址:http://www.cnblogs.com/tianex/p/5095200.html