Effective Java笔记第二章对所有对象都通用的方法
第三节始终要覆盖toString
1.toString的通用约定指出,被返回的字符串应该是一个"简洁的,但信息丰富并且易于阅读的表达形式",“建议所有的子类都覆盖这个方法”。
2.提供好的toString实现可以使类用起来更加舒适,当对象被传递给println,printf,字符串练操作符(+)以及assert或者被调试器打印出来的时候,toString方法就会被自动调用。
3.在实际应用中,toString方法应该返回对象中包含的所有指的关注的信息。
4.在实现toString的时候,必须要做一个很重要的决定:是否在文档中指定值的格式。对于值类来说建议这么做,指定格式的好处是可以被用做一种标准的,明确的,适合人阅读的对象表示法这种表示法可以用于输入和输出,以及用在永久的适合于人类阅读的数据对象中,例如XML文档。如果你指定了格式,最好再提供一个相匹配的静态工厂或者构造器,以便于程序员很容易的在对象和他的字符串表示法之间来回转换。
5.指定toString返回值的格式也有不足之处:如果这个类已经被广泛使用,一旦指定格式,就必须始终如一的坚持这种格式。程序员就会编写出相应的代码来解析这种字符串表示法,产生字符串表示法,以及把字符串表示法嵌入到持久的数据中。如果将来的发行版本中改变了这种表示法,就会破坏他们的代码和数据。如果不指定格式,就可以保留灵活性,便于在将来的发行版本中增加信息或者改进格式。
6.无论你是否决定指定格式,都应该在文档中明确的表明你的意图。
1)如果你要指定格式,应该严格的这样去做:
/**
* 返回此电话号码的字符串表示形式。
* 字符串由14个字符组成,格式为"(XXX) YYY-ZZZZ",其中XXX为区号,YYY为前缀,ZZZZ为行号(每个大写字母代表一个十进制数字)
*
* 如果有一些行号太短比如说是三位数,那么我们在开头用0来填充。例如,如果行号的值是123,则字符串表示形式的最后四个字符将是"0123"。
*
* 注意,区号后的右括号与前缀的第一个数字之间用一个空格隔开。
* @return
*/
@Override
public String toString() {
return String.format("(%03d) %03d-%04d",areaCode,prefix,lineNumber);
}
2)如果你不指定格式,那么文档的注释部分也应该有如下的指示信息:
/**
* 请返回关于号码的简要描述。具体的细节是不确定的,可能会改变,但以下可能被视为典型。
*
* PhoneNumber{areaCode=区号, prefix=前缀, lineNumber=行号}
* @return
*/
@Override
public String toString() {
return "PhoneNumber{" +
"areaCode=" + areaCode +
", prefix=" + prefix +
", lineNumber=" + lineNumber +
'}';
}
无论是否指定格式,都为toString返回值中包含的所有信息,提供一种编程式的访问途径。例如PhoneNumber类应该包含针对areaCode ,prefix 和lineNumber 的访问方法。如果不这么做,就会迫使那些需要这些信息的程序员不得不自己去解析这些字符串。除了降低程序的性能,使得程序员去做这些不必要的工作之外,这个解析过程很容易出错,会导致系统不稳定,如果格式发生变化,还会导致系统崩溃。