toString() 方法的作用是 将一个 Java 对象转换成字符串表示形式,以便于打印、记录日志或进行调试。

核心作用与场景
在 Java 中,每个对象都有一个默认的 toString() 方法,它继承自 Object 类,理解它的默认行为和如何重写它,是每个 Java 开发者的必备技能。
默认的 toString() 行为(来自 Object 类)
当你没有在自定义类中重写 toString() 方法时,调用 toString() 会返回一个看起来像这样的字符串:
类名@十六进制哈希码
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Person p = new Person("张三", 30);
// 没有重写 toString(),调用的是 Object 类的 toString()
System.out.println(p.toString());
// 直接打印对象时,Java 编译器会自动调用 toString() 方法
System.out.println(p);
}
}
输出结果:

Person@15db9742
Person@15db9742
这里的 15db9742 就是该对象在内存中的哈希码的十六进制表示,这个字符串对程序员来说信息量很少,我们无法从这个字符串中看出 Person 对象的具体内容(比如名字和年龄)。
为什么需要重写 toString()?
默认的 toString() 输出不直观,不包含对象的关键信息,在实际开发中,我们重写 toString() 的主要目的就是为了:
- 调试和日志记录:当我们在日志中打印一个对象时,希望看到的是它的具体状态(如属性值),而不是一串无意义的哈希码。
- 打印对象:当使用
System.out.println(obj)或类似方法时,能获得一个有意义的、可读的字符串。
如何重写 toString()?
重写 toString() 非常简单,只需要在你的类中提供一个没有参数、返回 String 类型的方法即可,一个好的 toString() 方法应该包含该对象最重要的属性信息。
示例:重写 Person 类的 toString()

public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 重写 toString() 方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
Person p = new Person("李四", 25);
System.out.println(p.toString()); // 显式调用
System.out.println(p); // 隐式调用
}
}
输出结果:
Person{name='李四', age=25}
Person{name='李四', age=25}
输出结果清晰明了,一眼就能看出这个 Person 对象的 name 和 age 属性的值。
最佳实践和技巧
-
总是使用
@Override注解 这是一个好习惯,它可以确保你确实是在重写父类的方法,而不是不小心创建了一个新的方法(比如把方法名拼写错了)。 -
包含关键信息
toString()应该返回一个包含对象“身份”或“状态”的字符串,这意味着包含所有或大部分实例变量的值。 -
格式清晰、一致 采用一种易于阅读的格式,
ClassName{property1=value1, property2=value2},这能让其他开发者(以及未来的你)快速理解输出。 -
利用 IDE 自动生成 现代化的 IDE(如 IntelliJ IDEA, Eclipse)可以一键为你生成高质量的
toString()方法。- 在 IntelliJ IDEA 中,右键 -> Generate -> toString()...
- 它会弹出一个窗口,让你选择要包含哪些字段,并自动生成代码。
-
考虑性能(对复杂对象) 对于非常复杂的对象,拼接字符串(使用 )可能会因为创建多个中间
String对象而导致性能问题,在这种情况下,可以使用StringBuilder来构建字符串。@Override public String toString() { return new StringBuilder() .append("Person{") .append("name='").append(name).append('\'') .append(", age=").append(age) .append('}') .toString(); }对于绝大多数应用场景,直接使用 拼接已经足够清晰且性能差异可以忽略不计。
toString() 与其他方法的关系
toString() 经常和以下两个方法一起被重写,以实现对象的完整“自我描述”:
-
equals(Object obj)toString()回答的是 “你是谁?” (What are you?)。equals()回答的是 “你和我相等吗?” (Are you the same as me?)。- 它们遵循一个约定:
a.equals(b)返回true,a.toString().equals(b.toString())也应该返回true,两个逻辑上相等的对象,它们的字符串表示也应该是相同的。
-
hashCode()hashCode()回答的是 “你在内存中的大致位置是哪里?” (Where are you likely to be?)。- 同样,它们也遵循一个约定:
a.equals(b)返回true,a.hashCode()必须等于b.hashCode()。
| 特性 | 描述 |
|---|---|
| 作用 | 将对象转换为字符串表示,主要用于打印、调试和日志。 |
| 默认行为 | 返回 类名@十六进制哈希码,信息量少,不实用。 |
| 核心目的 | 提供一个清晰、可读的字符串,包含对象的关键属性信息。 |
| 如何使用 | 在自定义类中重写该方法,返回一个描述对象状态的字符串。 |
| 最佳实践 | 使用 @Override 注解,包含关键信息,格式清晰,善用 IDE 生成。 |
| 相关方法 | 通常与 equals() 和 hashCode() 一起重写,以保持行为一致性。 |
toString() 是 Java 对象与人类世界沟通的桥梁,一个好的 toString() 实现能让你的代码调试和日志分析工作事半功倍。
