effective-Java/ch03所有对象的通用方法/12.始终重写toString方法.md
2019-10-10 20:10:34 +08:00

3.2 KiB
Raw Permalink Blame History

始终重写 toString 方法

虽然 Object 类提供了 toString 方法的实现,但它返回的字符串通常不是你的类的用户想要看到的。

toString 方法由类名后跟一个「at」符号@)和哈希码的无符号十六进制表示组成,例如 PhoneNumber@163b91

toString 的通用约定要求,返回的字符串应该是「一个简洁但内容丰富的表示,对人们来说是很容易阅读的」。

toString 通用约定「建议所有的子类重写这个方法」。

虽然它并不像遵守 equals 和 hashCode 约定那样重要,但是提供一个良好的 toString 实现使你的类更易于使用,并对使用此类的系统更易于调试。当对象被传递到 println、printf、字符串连接操作符或断言或者由调试器打印时toString 方法会自动被调用。即使你从不调用对象上的 toString其他人也可以。例如对对象有引用的组件可能包含在日志错误消息中对象的字符串表示。如果未能重写 toString则消息可能是无用的。

示例代码Item12Example01.java:重写 toString 方法。

指定 toString 返回值的格式的缺点是,假设你的类被广泛使用,一旦指定了格式,就会终身使用。程序员将编写代码来解析表达式,生成它,并将其嵌入到持久数据中。如果在将来的版本中更改了格式的表示,那么会破坏他们的代码和数据,并且还会抱怨。但通过选择不指定格式,就可以保留在后续版本中添加信息或改进格式的灵活性。

在静态工具类中编写 toString 方法是没有意义的。 你也不应该在大多数枚举类型(条目 34中写一个 toString 方法,因为 Java 为你提供了一个非常好的方法。 但是,你应该在任何抽象类中定义 toString 方法,该类的子类共享一个公共字符串表示形式。 例如,大多数集合实现上的 toString 方法都是从抽象集合类继承的。

使用AutoValue

AutoValue是一个可以自动为值类value type生成诸如equalshashCodetoString等模板方法的工具。

示例代码Item12Example02.java使用Google 的开放源代码 AutoValue 工具

编写一个 AutoValue 工具类:

  1. 这个类是抽象的。
  2. 抽象的字段访问函数,没有字段。
  3. 提供一个静态的创建函数返回该类对象。
  4. 类上标记@AutoValue注解。

在这里需要注意的是:

  • 实体类中AutoValue的前缀不能改变否则编译不会通过
  • 字段名称必须对应一致,实际参数列表和形参列表一致,否则编译不过;
  • AutoValue_PhoneNumber2 是根据AutoValue的命名格式AutoValue_类名来命名的。

在 pom.xml 中引入 Jar 包:

<dependency>
	<groupId>com.google.auto.value</groupId>
	<artifactId>auto-value-annotations</artifactId>
	<version>1.6.2</version>
</dependency>
<dependency>
	<groupId>com.google.auto.value</groupId>
	<artifactId>auto-value</artifactId>
	<version>1.6.2</version>
	<scope>provided</scope>
</dependency>