System.out.println打印对象时自动调用toString(),因println(Object)内部调用String.valueOf(x),而后者对非null对象直接调用obj.toString();若未重写,则使用Object默认实现(类名@哈希值);重写toString()可自定义输出格式。

Java中 System.out.println 打印对象时自动调用 toString(),是因为 println(Object) 方法内部会先调用该对象的 toString() 方法,再将返回的字符串输出。
println(Object) 的底层逻辑
System.out 是 PrintStream 类型,其 println(Object x) 方法定义如下:
它实际调用的是 String.valueOf(x),而 String.valueOf(Object obj) 的实现是:
也就是说,只要传入非 null 对象,就会直接调用它的 toString() 方法。
立即学习“Java免费学习笔记(深入)”;
为什么默认打印出的是类名+哈希码?
如果没重写 toString(),会继承自 Object 类的默认实现:
例如:com.example.User@1b6d3586。这不是“随机”,而是类全名加十六进制哈希值。
如何让打印更友好?重写 toString() 方法
在自定义类中显式重写 toString(),就能控制打印内容:
- 必须用
public修饰符,签名严格为public String toString() - 返回有意义的字符串,通常包含关键字段,推荐用 IDE 自动生成(如 IntelliJ 的
Alt+Insert→toString) - 避免在
toString()中抛异常或做耗时操作,它可能被日志、调试等频繁调用
示例:
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
此时 System.out.println(new User("Alice", 30)); 输出:User{name='Alice', age=30}
注意 null 和数组的特殊情况
System.out.println(null) 不会报空指针,而是直接输出字符串 "null";但数组对象不会自动展开内容,比如 int[] arr = {1,2,3}; System.out.println(arr); 仍会打印类似 [I@3a71f4dd —— 因为数组也继承自 Object,且没重写 toString()。如需可读格式,要用 Arrays.toString(arr)。



















