深入理解 Java Object
Java中的Object对象为所有对象的直接或间接父对象,里面定义的几个方法容易被忽略却非常重要。以下来自Effective Java 对Object中几个关键方法的应用说明。 PhoneNumber Cloneable,Comparable
equals(Object o)Object中equals方法的实现仅仅是比较了两个对象的地址,对于某些类来说正是所需用的、毋需复写的
什么时候需要对类的equals方法复写? 当一个类表示一个值,如String、Integer;它的不同实例需要逻辑上判断是否相同,而不仅仅是地址是否相同,此时需要复写来自定义相等的条件。由于Map的键和Set的元素都是唯一的,如何判断元素相同是使用此类集合的基础。 equals方法的复写需要满足以下通用约定
如无必要不要复写equals 方法,如果复写了此方法一定要记得复写hashCode方法,因为两个对象相等,它们的hashCode也要相等,下面是equals方法的常用步鄹
(o ==
(!(o c = (Collection>) o;
PhoneNumber pNum =
.linNum == pNum.linNum &&
.areaCode == pNum.areaCode &&
.prefix == }
当两个对象存在父子关系,并且子类添加新的值字段,在equals方法中使用instanceOf判断类型时容易破坏对称性或传递性,如Timestamp;使用getClass判断类型又违法里氏替换原则,所以避免使用继承,尝试使用组合;但如果父类是抽象的,不能实例化,则不会出现上述问题。
ColorPoint( x, point = .color =
(o ==
(!(o
ColorPoint cp =
cp.point.equals(point) &&
}
为什么不使用==比较浮点值,因为有两个例外使比较不一致
Float f1 =
Float f2 =
System.out.println(f1.floatValue() == f2.floatValue());
System.out.println(f2.equals(f1));
f1 = 0.0f
f2 = -0.0f
System.out.println(f1.floatValue() == f2.floatValue());
System.out.println(f2.equals(f1));
}
hashCode()上文说到如果复写equals方法一定要复写hashCode方法。下面说说hash值的计算
如果没有明确规范,发现更好的hash方法可以在以后版本修改
result = 0
result =
result = 31 * result +
result = 31 * result +
}
那些不可变对象如果hash值计算量大,需要使用缓存防止重复计算影响性能,这里线程不安全 hashCode = 0
result =
(result == 0
result =
result = 31 * result +
result = 31 * result +
}
toString()尽量复写toString方法,虽然不及equals和hashCode方法必要,但良好的类描述将能提供充分和友好的信息,AbstractCollection的toString为其子类统一提供集合信息的描述 如果要指定返回值的格式 可做如下说明 这样用户知道如何对其解析 但缺点是如果变更将导致以前的解析方式失败
String.format(Locale.CHINA,"%03d-%03d-%04d"
}
clone()如果一个class 实现了Cloneable接口 那么它应该 提供一个public clone方法
或者使用序列化的方式将对象写到磁盘中,再通过反序列化实现克隆对象,如Apache Commons3工具类,transient修饰的字段不会被序列化。
(PhoneNumber)
}
}
在实际中要实现对象拷贝,并不建议使用clone方法,而建议采用静态工厂或构造器方式提供复制操作 相比clone的优点:
比如某些集合类,以接口为参数的复制构造函数,还能实现转换复制
TreeSet(Collection E>
TreeMap(Map K,? V>
comparator =
}
ComparablecompareTo是个很重要的方法,虽然不是Object中的,因为和其他几个方法一样广泛应用,所以放在这里解释,实现Comparabe接口,复写compareTo方法后一个对象就有了可比较性。
建议如上使用基本数据类型包装类的静态比较方法compare ? 也可以使用Comparator接口里面的方法,在Java8中,可以如下生成按某种顺序比较的复合比较器。内部实现是从最后一个比较方法进入向前调用的
? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |