toString方法的规定

建议你始终要重写toString方法

虽然java.lang.Object提供了toString方法的一个实现,但它返回的字符串通常不是我们所希望看到的:

// test.ch02.PhoneNumber@12960c
System.out.println(new PhoneNumber(707, 867, 5309));

它会输出类的名称,以及一个@符号,借着是散列码的无符号十六进制表示法。

toString方法的通用约定是:被toString方法返回的字符串,应该是一个简洁的,但信息丰富,并且易于阅读的表达形式。

如何重写toString方法

在重写toString时,需要做出一个重要的决定:是否在toString中,制定返回值的格式。就拿上面的PhoneNumber来说,是否要返回一个707-867-5309的固定电话号码格式。

使用格式的好处是,toString方法会返回标准的、明确的、适合人阅读的对象表示法,例如:

@Override
public String toString() {
    return String.format("(%03d) %03d-%04d", areaCode, prefix, lineNumber);
}
// (707) 867-5309
System.out.println(new PhoneNumber(707, 867, 5309));

不足之处是,如果这个类被方法使用,一旦指定格式,就必须始终如一的坚持使用下去。

如果不定制格式,则可以凭自己的想法返回信息,现代IDE都会生成对象的信息。

无论是否使用格式,都应该在注释中,明确说明toString的意图。

例如要指定格式,注释可参考:

/**
     * 返回此电话号码的字符串表示形式。
     * 该字符串由十四个字符组成,其格式为“(XXX) YYY-ZZZZ”
     * XXX是areaCode,YYY是prefix,ZZZZ是lineNumber
     * <p>
     * 如果这个电话号码的三个部分都太小,不能填满它的字段,可以用0填充。
     * 例如lineNumber是"123",则可填写成"0123"。
     * <p>
     * 注意,(areaCode)和prefix中间有一个空格。
     */
    @Override
    public String toString() {
        return String.format("(%03d) %03d-%04d", areaCode, prefix, lineNumber);
    }

如果不指定格式,也应该在注释中有所指明:

/**
     * 返回一个简要说明,具体细节未经说明,并有可能发生变化。
     * 以下是一个简单的实例:
     * [PhoneNumber: areaCode=123, prefix=456, lineNumber=7890]
     */
    @Override
    public String toString() {
        return String.format("(%03d) %03d-%04d", areaCode, prefix, lineNumber);
    }

重写toString方法优化

  • 提供好的toString实现可以使类用起来更加舒适;
  • 在实际应用中,如果对象太大,或信息难以用字符串表达,就应该返回一个摘要信息;
  • 应该为toString返回值中包含的所有信息,提供一个getter方法;