[关闭]
@XingdingCAO 2018-02-13T15:36:25.000000Z 字数 2590 阅读 1616

Effective Java(第2版):item 10 —— Always override toString

Java


协议

虽然java.lang.Object提供了toString这一方法的实现,但是该方法返回的值却通常不是用户想看到的。这个值由类名、一个@以及该实例的无符号十六进制的哈希码组成,例如:PhoneNumber@163b91

toString的协议如下,其中重要的一点就是返回一个简短但又翔实的、易于理解的表述。PhoneNumber@163b91既简洁又易读,但是并不能提供多少有用的信息。相比之下,直接给出电话号码(+86)18888888888就有用多了。

此外,协议建议所有子类都重写这个方法,确实应该这样做。

toString

使用

虽然比不上遵守hashcode equals协议的重要性,但是提供一个良好地toString实现会让你的类使用起来更令人愉悦

toString方法在使用println printf、字符串连接符+assert或被调试器输出时自动调用。

printf方法自Java 1.5起被添加进平台中,相关的方法还有String.format,这个方法大致等同于C语言中的sprintf函数。

printf

假如你提供了一个良好的toString方法,那么生成下面的诊断信息就会十分简单:

  1. System.out.println("Failed to connect: " + phoneNumber)

无论你是否恰当地实现了toString方法,程序员都会以这种形式生成诊断信息。

良好的toString的受益者不限于一个类的实例,更包括含有实例引用的对象,尤其是集合对象。当你输出一个map时,哪一个你更愿意看到:{phoneNumber=PhoneNumber@163b91}还是{phoneNumber=(+86)18888888888}

实现

若实际可行,toString方法应该包含对象中所有令人感兴趣的信息。但是,当对象过于庞大,又或者对象包含了难以转换为文字的状态时,这一目标并不可行。这些情形下,toString应该返回一个概要,例如:“Manhattan white pages (1487536 listings)” “Thread[main, 5, main]”。

理想的情况下,产生的文本应该是一目了然的。(可惜,Thread并未通过本项)

格式

在实现toString时,需要做出一个重要的决定:是否确定返回文本的格式,以及将其写入文档中。通常对于value classes的建议是肯定的。例如:电话号码、矩阵等。

优势

明确格式的好处是:格式作为一个标准,消除了歧义,使得可读性提高。格式可以用于输入或输出,以及一些持久化的、可读的数据对象中(例如:XML文件)。

如果你确定了格式,那么最好也提供一个与之匹配的静态工厂或构造方法,以此来方便对象与其文本表示的相互转化。这种方法被Java平台的类库中的众多value class所采用,例如:BigInteger BigDecimal 以及大多数装箱的原始类型。

劣势

明确toString返回值的格式的劣势就是,一旦你明确了格式,那么你将一直陷入其中(假定你的类被广泛使用)。程序员会编写转换表述的代码,生成之后,将会裹入持久的数据中。如果你在新的发行版中更改了表述,那么代码和数据之间的纽带将会被破坏。不去明确文本的格式,你保有在接下来的发行中添加或改进格式的灵活。

总结

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注