Java toString() 方法
最后更新:2025年4月7日
1. 概述
Java 中的每个类都直接或间接继承自 Object 类。由于 Object 类包含一个 toString() 方法,因此我们可以对任何实例调用 toString() 并获取其字符串表示形式。
在本教程中,我们将查看 toString() 的**默认行为,并学习如何更改其行为。**
2. 默认行为
每当我们打印一个对象引用时,它会在内部调用 toString() 方法。因此,如果我们未在类中定义 toString() 方法,则会调用 Object#toString()。
Object 的 toString() 方法非常通用
public String toString() {
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
为了查看其工作原理,让我们创建一个 Customer 对象,我们将会在整个教程中使用它
public class Customer {
private String firstName;
private String lastName;
// standard getters and setters. No toString() implementation
}
现在,如果我们尝试打印我们的 Customer 对象,Object#toString() 将被调用,输出将类似于
com.baeldung.tostring.Customer@6d06d69c
3. 重写默认行为
从上面的输出中可以看出,它没有提供太多关于我们的 Customer 对象内容的信息。**通常,我们对知道对象的哈希码不感兴趣,而是对对象属性的内容感兴趣。**
通过重写 toString() 方法的默认行为,我们可以使方法调用的输出更有意义。
现在,让我们看看一些使用对象的不同场景,看看如何重写此默认行为。
4. 原始类型和 Strings
我们的 Customer 对象同时具有 String 和原始属性。我们需要重写 toString() 方法以获得更有意义的输出
public class CustomerPrimitiveToString extends Customer {
private long balance;
@Override
public String toString() {
return "Customer [balance=" + balance + ", getFirstName()=" + getFirstName()
+ ", getLastName()=" + getLastName() + "]";
}
}
让我们看看现在调用 toString() 后会得到什么
@Test
public void givenPrimitive_whenToString_thenCustomerDetails() {
CustomerPrimitiveToString customer = new CustomerPrimitiveToString();
customer.setFirstName("Rajesh");
customer.setLastName("Bhojwani");
customer.setBalance(110);
assertEquals("Customer [balance=110, getFirstName()=Rajesh, getLastName()=Bhojwani]",
customer.toString());
}
5. 复杂的 Java 对象
现在,让我们考虑一种情况,我们的 Customer 对象也包含一个 order 属性,该属性的类型为 Order。我们的 Order 类同时具有 String 和原始数据类型字段。
所以,让我们再次重写 toString()
public class CustomerComplexObjectToString extends Customer {
private Order order;
//standard setters and getters
@Override
public String toString() {
return "Customer [order=" + order + ", getFirstName()=" + getFirstName()
+ ", getLastName()=" + getLastName() + "]";
}
}
由于 order 是一个复杂对象,如果我们只是打印我们的 Customer 对象,而没有在我们的 Order 类中重写 toString() 方法,它将把 orders 打印为 Order@<hashcode>。
为了解决这个问题,让我们也重写 Order 中的 toString()
public class Order {
private String orderId;
private String desc;
private long value;
private String status;
@Override
public String toString() {
return "Order [orderId=" + orderId + ", desc=" + desc + ", value=" + value + "]";
}
}
现在,让我们看看在我们的 Customer 对象上调用 toString() 方法(其中包含 order 属性)时会发生什么
@Test
public void givenComplex_whenToString_thenCustomerDetails() {
CustomerComplexObjectToString customer = new CustomerComplexObjectToString();
// .. set up customer as before
Order order = new Order();
order.setOrderId("A1111");
order.setDesc("Game");
order.setStatus("In-Shiping");
customer.setOrders(order);
assertEquals("Customer [order=Order [orderId=A1111, desc=Game, value=0], " +
"getFirstName()=Rajesh, getLastName()=Bhojwani]", customer.toString());
}
6. 对象数组
接下来,让我们将我们的 Customer 更改为具有一个 Order 的数组。如果只是打印我们的 Customer 对象,而没有对我们的 orders 对象进行特殊处理,它会将 orders 打印为 Order;@<hashcode>。
为了解决这个问题,让我们对 orders 字段使用 Arrays.toString()
public class CustomerArrayToString extends Customer {
private Order[] orders;
@Override
public String toString() {
return "Customer [orders=" + Arrays.toString(orders)
+ ", getFirstName()=" + getFirstName()
+ ", getLastName()=" + getLastName() + "]";
}
}
让我们查看调用上述 toString() 方法的结果
@Test
public void givenArray_whenToString_thenCustomerDetails() {
CustomerArrayToString customer = new CustomerArrayToString();
// .. set up customer as before
// .. set up order as before
customer.setOrders(new Order[] { order });
assertEquals("Customer [orders=[Order [orderId=A1111, desc=Game, value=0]], " +
"getFirstName()=Rajesh, getLastName()=Bhojwani]", customer.toString());
}
7. 包装类、集合和 StringBuffers
当对象完全由 包装类、集合 或 StringBuffers 组成时,不需要自定义 toString() 实现,因为这些对象已经使用有意义的表示形式重写了 toString() 方法
public class CustomerWrapperCollectionToString extends Customer {
private Integer score; // Wrapper class object
private List<String> orders; // Collection object
private StringBuffer fullname; // StringBuffer object
@Override
public String toString() {
return "Customer [score=" + score + ", orders=" + orders + ", fullname=" + fullname
+ ", getFirstName()=" + getFirstName() + ", getLastName()=" + getLastName() + "]";
}
}
让我们再次查看调用 toString() 的结果
@Test
public void givenWrapperCollectionStrBuffer_whenToString_thenCustomerDetails() {
CustomerWrapperCollectionToString customer = new CustomerWrapperCollectionToString();
// .. set up customer as before
// .. set up orders as before
customer.setOrders(new Order[] { order });
StringBuffer fullname = new StringBuffer();
fullname.append(customer.getLastName()+ ", " + customer.getFirstName());
assertEquals("Customer [score=8, orders=[Book, Pen], fullname=Bhojwani, Rajesh, getFirstName()=Rajesh, "
+ "getLastName()=Bhojwani]", customer.toString());
}
8. 结论
在本文中,我们研究了创建自己的 toString() 方法实现。
支持本文的代码可在 GitHub 上获取。 一旦你以 Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。















