toString方法
虽然Object本身有一个toString的实现,但toString的通用约定指出,“建议所有的子类覆盖这个方法”,我们应该通过覆盖toString方法为对象的打印提供更简洁明确的信息。
使用toString方法时,有一个需要谨慎考虑的问题就是是否需要为返回值确定一个格式,比如为一个自定义的Date类实现一个toString方法,返回一个“yyyy-MM-dd”格式的字符串,这种方法有好有坏,好处是可以提供一个标准的、明确的、适合人阅读的对象表示法,坏处是一旦确定了格式并且被广泛使用,就必须一如既往的使用这种格式,一旦随意变动,往往会破坏使用你这个类的程序员们针对这个字符串编写的用于解析的代码。
所以无论指不指定格式,最保险的是每次都在文档注释中说明你的意图。
另外需要注意的是,**无论是否指定格式,都要为toString方法返回值中包含的信息提供一种编程式的访问途径,例如上面提到的自定义Date类,如果返回值是“yyyy-MM-dd”,就需要有对应的方法返回yyyy、MM和dd这三个值。
考虑实现Comparable接口
与前面提到的方法不同,Comparable接口和它的compareTo方法与object类没什么关系,但在effective java中也将它放在了对于所有对象通用方法的一章中,其实很好理解,我们实现的很多对象是需要进行排序这种需求的。而这个接口和它的方法也就是为这种需求而存在的,如果你在编写的类具有非常明显的内在排序关系,比如按字母、按数值或者按时间排序,那么就坚决应该实现这个接口。
就像破坏了hashCode通用约定会破坏其他依赖于散列算法的类的使用一样,如果破坏了Comparable接口的通用约定,也会破坏其他依赖于比较关系的类,比如TreeSet、TreeMap、Collections和Arrays,它们内部包含有搜索和排序算法。
那么Comparable的通用约定是什么呢,其实Comparable的通用约定可以和equals相互呼应,同样要有对应比较运算的自反性、传递性、对称性,因此和equals相同,在为一个类扩展了新的值组件后,无法保证其compareTo方法的可用性和正确性。解决这个问题的权宜之计是编写一个不相关的类,用这个类包含原先的类的实例,然后用一个“视图”(View)方法返回这个实例。这样既可以在第二个类上自由的编写compareTo方法,同时也允许它的客户端在需要的时候把第二个类的实例视同第一个类的实例。
compareTo约定的一个强烈的建议是,如果x.compareTo(y)==0,那么同样成立x.equals(y),这只是一个强烈的建议,因为即使compareTo方法的结果与equals不同,这个类仍然能正常工作,但是一般来说,如果你的类实现的compareTo方法与这条建议不符,还是应该给予明确的说明:”该类具有内在排序功能,但与equals不一致“。