1.为什么要覆盖toString方法?
public class Person {
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
/*@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}*/
public static void main(String[] args) {
Person s = new Person("liming", 6);
System.out.println(s);
}
}
如果不覆盖打印:
demo6.Person@1636731
覆盖打印:
@Override
public String toString() {
return "\nname: " + name + "\nage: " + age;}
Person [name=liming, age=6]
虽然java.lang.Object提供了toString方法的一个实现,但它返回的字符串通常并不是类的用户所期望看到的。
尽管有人认为“Person@1636731”算得上简洁和易于阅读,但是与“Person [name=liming, age=12]”比较起来,它还算不上信息丰富的。它包含类的名称,以及一个“@”符号,接着是散列码的无符号十六进制表示法,例如“Person@1636731”。
toString的约定进一步指出,建议所有的类都覆盖这个方法。
2、无论你是否指定格式,都要在文档中明确
- 是否指定格式,都为toString 返回值中包含的信息,提供了一种编程式的访问路径
- 无论与否,都请在文档中表明你的意图
toString()方法的通用约定是:返回当前对象“简洁,但信息丰富,并且易于阅读的表达形式”。
指定toString返回值的格式有不足之处:如果这个类已经被广泛使用,一旦指定格式,就必须始终如一地坚持这种格式。无论是否决定指定格式,都应该在文档中明确地表明意图。
3 Guava关于toString的
Guava通过 Objects.toStringHelper为我们提供了方便创建toString的方法。看下面的样例:
/ Returns "ClassName{x=1}"
Objects.toStringHelper(this)
.add("x", 1)
.toString();
// Returns "MyObject{x=1}"
Objects.toStringHelper("MyObject")
.add("x", 1)
.toString();
Guava关于toString的文档连接: https://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained
// 重写PhoneNumber的toString方法 - Effective Java中文第二版第44页
package org.effectivejava.examples.chapter03.item10;
import java.util.HashMap;
import java.util.Map;
import com.google.common.base.Objects;
public final class PhoneNumber {
private final short areaCode;
private final short prefix;
private final short lineNumber;
public PhoneNumber(int areaCode, int prefix, int lineNumber) {
rangeCheck(areaCode, 999, "area code");
rangeCheck(prefix, 999, "prefix");
rangeCheck(lineNumber, 9999, "line number");
this.areaCode = (short) areaCode;
this.prefix = (short) prefix;
this.lineNumber = (short) lineNumber;
}
private static void rangeCheck(int arg, int max, String name) {
if (arg < 0 || arg > max)
throw new IllegalArgumentException(name + ": " + arg);
}
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof PhoneNumber))
return false;
PhoneNumber pn = (PhoneNumber) o;
return pn.lineNumber == lineNumber && pn.prefix == prefix
&& pn.areaCode == areaCode;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber;
return result;
}
//Effective Java原有的toString方法
/*
* @Override public String toString() { return
* String.format("(%03d) %03d-%04d", areaCode, prefix, lineNumber); }
*/
/**
* 采用Guava实现的toString
*
*/
@Override
public String toString() {
return Objects.toStringHelper(this)
.addValue(String.format("(%03d) %03d-%04d", areaCode, prefix,lineNumber))
.add("areaCode", areaCode)
.add("prefix", prefix)
.add("lineNumber", lineNumber)
.toString();
}
public static void main(String[] args) {
Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put(new PhoneNumber(707, 867, 5309), "Jenny");
System.out.println(m);
}
}
输出对比
//原输出
{(707)
867-5309=Jenny}
//Guava实现输出
{PhoneNumber{(707)
867-5309, areaCode=707, prefix=867, lineNumber=5309}=Jenny}
4.结论
覆盖toString就是为了调试或者打印的时候可以更直观的看到对象的有用的信息,所以建议写新写类的时候要覆盖toString方法。
5.参考文献
https://www.jianshu.com/p/05bf27bb2efc
https://www.javatt.com/p/6191
本公众号分享自己从程序员小白到经历春招秋招斩获10几个offer的面试笔试经验,其中包括【Java】、【操作系统】、【计算机网络】、【设计模式】、【数据结构与算法】、【大厂面经】、【数据库】期待你加入!!!
1.计算机网络----三次握手四次挥手
2.梦想成真-----项目自我介绍
3.你们要的设计模式来了
4.一字一句教你面试“个人简介”
5.接近30场面试分享