Java toString() Method – Java toString()方法

最后修改: 2019年 1月 11日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Every class in Java is a child of the Object class either directly or indirectly. And since the Object class contains a toString() method, we can call toString() on any instance and get its string representation.

Java中的每一个类都是Object类的子类,无论是直接还是间接。由于Object类包含一个toString()方法,我们可以在任何实例上调用toString()并获得其字符串表示。

In this tutorial, we’ll look at the default behavior of toString() and learn how to change its behavior.

在本教程中,我们将研究toString()的默认行为,并学习如何改变其行为。

2. Default Behavior

2.默认行为

Whenever we print an object reference, it invokes the toString() method internally. So, if we don’t define a toString() method in our class, then Object#toString() is invoked.

每当我们打印一个对象引用时,它就会在内部调用toString()方法。所以,如果我们没有在我们的类中定义一个toString()方法,那么Object#toString()会被调用。

Object’s toString() method is pretty generic:

Object的 toString()方法是相当通用的。

public String toString() {
    return getClass().getName()+"@"+Integer.toHexString(hashCode());
}

To see how this works, let’s create a Customer object that we’ll use throughout our tutorial:

为了了解这一点,让我们创建一个Customer 对象,我们将在整个教程中使用这个对象。

public class Customer {
    private String firstName;
    private String lastName;
    // standard getters and setters. No toString() implementation
}

Now, if we try to print our Customer object, Object#toString() will be called, and the output will be similar to:

现在,如果我们试图打印我们的C客户对象,Object#toString()将被调用,输出将类似于。

com.baeldung.tostring.Customer@6d06d69c

3. Overriding Default Behavior

3.覆盖默认行为

Looking at the above output, we can see that it doesn’t give us much information about the contents of our Customer object. Generally, we aren’t interested in knowing the hashcode of an object, but rather the contents of our object’s attributes.

看看上面的输出,我们可以看到它并没有给我们提供关于Customer 对象内容的很多信息。一般来说,我们对知道一个对象的哈希代码不感兴趣,而是对我们对象的属性内容感兴趣。

By overriding the default behavior of the toString() method, we can make the output of the method call more meaningful.

通过覆盖toString()方法的默认行为,我们可以使方法调用的输出更加有意义。

Now, let’s look at a few different scenarios using objects to see how we can override this default behavior.

现在,让我们看一下使用对象的几个不同场景,看看我们如何能够覆盖这个默认行为。

4. Primitive Types and Strings

4.原始类型和字符串

Our Customer object has both String and primitive attributes. We need to override the toString() method to achieve a more meaningful output:

我们的Customer对象同时拥有String和原始属性。我们需要覆盖toString()方法来实现更有意义的输出。

public class CustomerPrimitiveToString extends Customer {
    private long balance;

    @Override
    public String toString() {
        return "Customer [balance=" + balance + ", getFirstName()=" + getFirstName()
          + ", getLastName()=" + getLastName() + "]";
    }
}

Let’s see what we get when we call toString() now:

让我们看看当我们现在调用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. Complex Java Objects

5.复杂的Java对象

Let’s now consider a scenario where our Customer object also contains an order attribute that is of type Order. Our Order class has both String and primitive data type fields.

现在让我们考虑一个场景,我们的 Customer 对象也包含一个 order 属性,该属性是 Order 类型的。我们的Order类有String和原始数据类型字段。

So, let’s override toString() again:

所以,让我们再次覆盖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() + "]";
    }      
}

Since order is a complex object, if we just print our Customer object, without overriding the toString() method in our Order class, it will print orders as Order@<hashcode>.

由于order是一个复杂的对象如果我们只是打印我们的Customer对象,而不在我们的Order类中覆盖toString() 方法,它将打印Order作为Order@<hashcode>。

To fix that let’s override toString() in Order, too:

为了解决这个问题,我们也在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 + "]";
    }
}

Now, let’s see what happens when we call the toString() method on our Customer object that contains an order attribute:

现在,让我们看看当我们在包含order 属性的Customer对象上调用toString()方法时会发生什么。

@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. Array of Objects

6.对象阵列

Next, let’s change our Customer to have an array of Orders. If we just print our Customer object, without special handling for our orders object, it will print orders as Order;@<hashcode>.

接下来,让我们改变我们的Customer,使其拥有一个Orders数组。如果我们只是打印我们的Customer对象,而不对我们的orders对象进行特殊处理,它将打印ordersOrder;@<hashcode>

To fix that let’s use Arrays.toString() for the orders field:

为了解决这个问题,让我们使用Arrays.toString()来处理orders字段。

public class CustomerArrayToString  extends Customer {
    private Order[] orders;

    @Override
    public String toString() {
        return "Customer [orders=" + Arrays.toString(orders) 
          + ", getFirstName()=" + getFirstName()
          + ", getLastName()=" + getLastName() + "]";
    }    
}

Let’s see the results of calling the above toString() method:

让我们看看调用上述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. Wrappers, Collections, and StringBuffers

7.封装器、集合和StringBuffers

When an object is made up entirely of wrappers, collections, or StringBuffers, no custom toString() implementation is required because these objects have already overridden the toString() method with meaningful representations:

当一个对象完全由包装器集合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() + "]";
    }
}

Let’s again see the results of calling toString():

让我们再次看看调用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. Conclusion

8.结语

In this article, we looked at creating our own implementations of the toString() method.

在这篇文章中,我们研究了创建我们自己的toString()方法的实现。

All of the source code for this article is available over on GitHub.

本文的所有源代码都可以在GitHub上找到