专栏首页MyBlogEffective.Java 读书笔记(10)关于toString

Effective.Java 读书笔记(10)关于toString

10.Always override toString

针对于java.lang.Object已经帮我们实现好了的toString方法,当我们自己定义出来的类使用这古老的toString方法的时候,通常不会返回给你一个比较满意的字符串

那这个字符串由什么组成呢?

首先是有一个类名,加上一个“@”的符号,然后加上这个类的hash code的无符号16进制表示

举个例子,比如上一篇关于HashCode的文章中的PhoneNumber类

那么它的hash code就是这个样子: PhoneNumber@163b91

在JavaSE6中对于toString方法的规范是这样说的:

"a concise but informative representation that is easy for a person to read"

大意为 简洁而不失可读性和信息的表现

对于“PhoneNumber@163b91”这样的形式来说,十分简洁,同时也具有一定的可读性,就是信息的表现略晦涩,难以理解

比起” (707) 867-5309 “ 上面形式的信息的表现力就弱了许多

那么JavaSE6想和我们说其实就是:

建议所有子类重写toString方法!

的确是个好的建议

需要注意的是,重写toString方法的重要性可能不会像我们之前说提过的equals和hashCode方法来的重要,但是,重写这个方法并且对这个方法做出一个漂亮的实现会让我们的类用起来更加的愉快,甚至说,优雅!

当一个类作为参数传递给println,printf,字符串的连接操作符,或者assert,被debugger打印啊之类的,就会自动地调用这个类的toString方法

printf是1.5之后才加进来的方法,依赖于String.format,这个方法就特别像C语言中的sprintf函数

如果你实现好了这个toString方法,那么你在打印一些调试信息的时候就特别的轻松,如下

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

不管你是否重写了toString方法,程序员们都会试图像上面这样来打印调试信息,只不过,如果你好好的重写了该方法,那么这条信息就比你不重写的时候所产生的信息来的有用

重写一个好的toString方法不仅仅对本类产生作用,它还会延伸到那些拥有该类引用的那些对象的身上!

举个例子,比如说Collection这样的集合类,当你打印Map的时候你会更加愿意看到“ {Jenny=PhoneNumber@163b91} ”还是“ {Jenny=(707) 867-5309} ”呢?

实际应用中,toString方法需要返回该对象的所有的有意思的信息

正如我们之前提到的phoneNumber类,如果有这么一个集合包含了成千上万的phoneNumber,那么它应该返回一个概括性的描述,这个描述就类似于”Manhattan white pages (1487536 listings)“,这样的形式,而不是返回那么多条数据

理想条件下,我们希望返回的这个string应当是不言自明的

你还需要做的一个重要的事情就是,当你实现toString方法的时候,是否要在文档中指定返回值的格式

对于那些值依赖的类来说,比如电话号码,矩阵之类的,推荐的做法应该是在文档中指定返回值的格式,这样做的优点在于使得一个对象的表述变得标准,明确而且具有可读性,这样的表达可以被输入或者输出在人类可读的持久型数据对象中,比如说XML文档

如果你指定了返回值的格式,那么较好的做法是在类中添加静态工厂或者构造方法,这样利于程序的拓展之类的,这样的方法被应用在Java 平台库中,比如 BigInteger , BigDecimal 以及那些对基本类型的封装类

指定返回值格式的缺点在于,你的程序的灵活性将降低,也就是说你一旦重新改了这个格式,那么很多以往的程序就无法兼容了,这是我们需要好好考虑的

不管你打不打算指定返回值的格式,你都应该在文档中清楚地说明你的打算,举个例子:

/**
* Returns the string representation of this phone number.
* The string consists of fourteen characters whose format
* is "(XXX) YYY-ZZZZ", where XXX is the area code, YYY is
* the prefix, and ZZZZ is the line number. (Each of the
* capital letters represents a single decimal digit.)
*
* If any of the three parts of this phone number is too small
* to fill up its field, the field is padded with leading zeros.
* For example, if the value of the line number is 123, the last
* four characters of the string representation will be "0123".
*
* Note that there is a single space separating the closing
* parenthesis after the area code from the first digit of the
* prefix.
*/
@Override public String toString() {
    return String.format("(%03d) %03d-%04d",
    areaCode, prefix, lineNumber);
}

有了这些说明,在你的程序的基础上进行开发的人就不会因为格式修改而责怪你了

需要注意的是,你必须对toString返回的各类信息所在的域提供编程访问,这对于整个系统的构建有着极其重要的意义

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • A Survey on Dialogue Systems: Recent Advances and New Frontiers 论文笔记

    对话系统受到越来越多人的关注, 深度学习的兴起也带动了一系列研究的发展, 深度学习能够利用大量的数据和少量的人工处理来学习有意义的特征表达以及回答的生成策略, ...

    Mezereon
  • 数值分析读书笔记(1)导论

    一般来说,解决实际问题的第一步是将实际问题转换为数学问题,接着建立数学模型来解决这个数学问题,而理论解或者解析解通常难以求得,于是数值计算的方法应运而生

    Mezereon
  • Effective.Java 读书笔记(1)静态工厂和构造方法

    用户在获得类它本身的实例的时候,通常会想到的就是使用public的构造器,但是一个类可以提供一个public的工厂方法。 这种工厂方法简化了返回该类实例的静态...

    Mezereon
  • 噪音:让生成模型稳定训练的技巧

    Generative Adversarial Networks (GANs) are notoriously hard to train. In a recen...

    用户1908973
  • 多径环境下的新型双基地联合雷达通信系统(CS)

    在联合雷达通信(JRC)系统中,雷达探测和通信可以同时运行。在本文中,我们提出了一种适用于多路径环境的双基地JRC系统。基于一种新的联合波形,针对目标检测和信道...

    DDDDDaemon
  • 什么是SAP UI5的Component-preload.js

    First of all, the Component-preload.js works as expected. In your design time, (...

    Jerry Wang
  • 什么是SAP UI5的Component-preload.js

    First of all, the Component-preload.js works as expected. In your design time, (...

    Jerry Wang
  • SAP Fiori Elements Object Page页面渲染原理

    I have already been working with Smart template for one month. Since now no fron...

    Jerry Wang
  • PVT, RC Variation & OCV

    PVT is abbreviation for Process, Voltage and Temperature. In order to make our c...

    白山头
  • cmake:vs2015/MinGW静态编译leveldb

    leveldb是google的开源项目(https://github.com/google/leveldb), 在linux下编译很方便,然而官方版本却没有提供...

    用户1148648

扫码关注云+社区

领取腾讯云代金券