toString() 方法是 Java 中一个非常重要且基础的方法,当你在代码中尝试打印一个对象时(例如使用 System.out.println(myObject)),Java 虚拟机(JVM)会自动调用该对象的 toString() 方法来获取其字符串表示形式。

toString() 的基本格式
toString() 方法定义在 Object 类中,其原始格式如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
默认格式的示例:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("张三", 30);
System.out.println(p); // 隐式调用 p.toString()
System.out.println(p.toString());
}
}
输出结果:
com.example.Person@15db9742 // com.example.Person 是类的全限定名,@ 后面是哈希码的十六进制表示
com.example.Person@15db9742
这个默认的输出对于调试来说没有太大帮助,因为它没有包含任何关于对象状态(如 name 和 age)的信息。强烈建议在你创建的每一个类中都重写(override)toString() 方法。

推荐的 toString() 格式(最佳实践)
一个好的 toString() 方法应该清晰、简洁,并且能够提供对象关键状态的描述性信息,业界普遍遵循以下格式:
ClassName[field1=value1, field2=value2, ...]
优点:
- 清晰易懂:一眼就能看出对象的类型和各个字段的值。
- 结构化:方括号
[]和逗号 提供了良好的结构,便于阅读和解析。 - 调试利器:在日志、调试器或打印对象时非常有用。
示例:实现推荐的格式
我们为 Person 类重写 toString() 方法:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
// 使用 StringBuilder 来构建字符串,性能更优
return "Person[name=" + this.name + ", age=" + this.age + "]";
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("张三", 30);
System.out.println(p);
}
}
输出结果:

Person[name=张三, age=30]
这个输出信息就非常清晰和有用了。
现代化实现方式(推荐)
手动拼接字符串虽然简单,但当对象字段很多时,代码会变得冗长且容易出错,Java 提供了更优雅的方式来生成 toString() 方法。
a) 使用 StringBuilder 或 StringBuffer
这是手动拼接的优化版,性能更好,因为它避免了创建多个中间字符串对象。
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Person[");
sb.append("name='").append(name).append('\'');
sb.append(", age=").append(age);
sb.append(']');
return sb.toString();
}
b) 使用 Java 5+ 的 String.format()
这种方式更具可读性,类似于 C 语言的 printf。
@Override
public String toString() {
return String.format("Person[name='%s', age=%d]", name, age);
}
c) 使用 IDE 自动生成
这是最常用、最推荐的方法!所有主流的 Java IDE(如 IntelliJ IDEA, Eclipse, VS Code)都可以一键为你生成规范的 toString() 方法。
- 在 IntelliJ IDEA 中:
- 在代码编辑器中右键点击。
- 选择
Generate...(或按Alt + Insert)。 - 选择
toString()。 - 在弹出的窗口中选择需要包含在输出中的字段,点击
OK。
IDE 生成的代码通常非常健壮,并且考虑了空值处理。
d) 使用 Lombok 库(在大型项目中非常流行)
Lombok 通过注解来自动生成 toString() 以及其他如 equals(), hashCode(), getter/setter 等方法。
只需在你的类上添加 @ToString 注解即可。
import lombok.ToString;
@ToString // Lombok 会自动生成 toString() 方法
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("李四", 25);
System.out.println(p);
}
}
输出结果:
Person(name=李四, age=25)
Lombok 还支持一些有用的配置,exclude 排除某些字段,of 只包含指定字段等。
格式化进阶技巧
a) 处理 null 值
如果对象的某个字段可能为 null,直接拼接可能会导致 NullPointerException,有几种处理方式:
- 提供默认值:
"name=" + (name != null ? name : "N/A") - 使用
Objects.toString()(Java 7+):"name=" + Objects.toString(name, "N/A")(更简洁) - 使用
String.valueOf():"name=" + String.valueOf(name)(name为null,会输出字符串"null")
b) 格式化日期、数字等对象
如果字段是 Date, BigDecimal, LocalDate 等复杂类型,直接调用 toString() 可能不够友好,应该使用专门的格式化工具。
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
class Product {
private String name;
private BigDecimal price;
private LocalDate releaseDate;
// ... constructor, getters ...
@Override
public String toString() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return String.format("Product[name='%s', price=$%.2f, releaseDate=%s]",
name,
price, // BigDecimal 会自动格式化为两位小数
releaseDate.format(formatter));
}
}
输出结果:
Product[name='Super Widget', price=$99.99, releaseDate=2025-10-27]
| 方法 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|
默认 Object.toString() |
无需实现 | 无意义,无法用于调试 | ⭐ |
| 手动拼接 | 简单直接 | 性能差,代码冗长,易出错 | ⭐⭐ |
StringBuilder |
性能好,灵活 | 代码相对繁琐 | ⭐⭐⭐ |
String.format() |
可读性高 | 性能略逊于 StringBuilder |
⭐⭐⭐⭐ |
| IDE 自动生成 | 最佳实践,规范、高效、健壮 | 需要使用 IDE | ⭐⭐⭐⭐⭐ |
Lombok @ToString |
极致简洁,减少样板代码 | 引入外部依赖,团队需统一使用 | ⭐⭐⭐⭐⭐ |
核心建议:
- 永远重写
toString(),除非你的类确实不需要被打印或调试。 - 优先使用 IDE 的自动生成功能,它是最快、最规范、最不容易出错的方式。
- 遵循
ClassName[field1=value1, ...]的通用格式,这会让你的代码更易于被其他开发者理解。 - 妥善处理
null值和复杂对象,确保输出信息始终清晰、友好。
