1. Обзор
Каждый класс в Java является дочерним по отношению к классу Object прямо или косвенно. И поскольку класс Object содержит метод toString () , мы можем вызвать toString() в любом экземпляре и получить его строковое представление.
В этом уроке мы рассмотрим поведение по умолчанию toString() и узнаем, как изменить его поведение.
2. Поведение по умолчанию
Всякий раз, когда мы печатаем ссылку на объект, он вызывает метод toString() внутренне. Итак, если мы не определяем метод toString() в нашем классе, то вызывается Object# toString () .
Метод объекта 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 }
Теперь, если мы попытаемся напечатать наш C ustomer объект, Object # toString() будет вызван, и результат будет похож на:
3. Переопределение Поведения По умолчанию
Глядя на приведенный выше вывод, мы видим, что он не дает нам много информации о содержимом нашего объекта Customer . Как правило, мы не заинтересованы в знании хэш-кода объекта, а скорее в содержании атрибутов нашего объекта.
Переопределяя поведение по умолчанию метода toString () , мы можем сделать вывод вызова метода более значимым.
Теперь давайте рассмотрим несколько различных сценариев с использованием объектов, чтобы понять, как мы можем переопределить это поведение по умолчанию.
4. Примитивные типы и строки
Наш объект 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() + "]"; } }
С приказ является сложным объектом , если мы просто распечатаем Покупатель объект, не переопределяя toString() метод в нашем Заказ класс, он будет печатать заказы как [электронная почта защищена] <хэш-код>.
Чтобы исправить это , давайте переопределим 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 + "]"; } }
Теперь давайте посмотрим, что происходит, когда мы вызываем метод toString() для нашего объекта Customer , который содержит атрибут 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. Массив объектов
Далее, давайте изменим наш Клиент , чтобы иметь массив Order s . Если мы просто напечатаем наш объект Customer без специальной обработки для нашего объекта orders , он будет печатать orders как Order;@ .
Чтобы исправить это, давайте использовать 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() + "]"; } }
Давайте посмотрим на результаты вызова вышеупомянутого метода 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 , никакая пользовательская реализация toString() не требуется, поскольку эти объекты уже переопределили метод toString() со значимыми представлениями:
public class CustomerWrapperCollectionToString extends Customer { private Integer score; // Wrapper class object private Listorders; // 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 .