Каждый Java-разработчик сталкивался с необходимостью отладки кода или логирования состояния объектов. И здесь на помощь приходит метод toString() — один из базовых методов класса Object. Но писать его вручную для каждого класса — занятие утомительное и чреватое ошибками. Именно для решения этой проблемы и существует ToStringBuilder.
ToStringBuilder это вспомогательный класс, предоставляемый библиотекой apache commons lang. Он обеспечивает полный и лучший контроль над тем, какие данные объекта и в каком количестве должны выводиться методом toString(), а также в каком формате.
Maven:
org.apache.commons
commons-lang3
3.14.0
Gradle:
implementation 'org.apache.commons:commons-lang3:3.14.0'
Важно: Используйте commons-lang3 (пакет org.apache.commons.lang3), а не устаревший commons-lang версии 2.x. Старая версия больше не поддерживается.
Чтобы продемонстрировать различные возможности использования ToStringBuilder для построения метода toString() в различных сценариях, я создам три модели: AbstractUser.java, WebUser.java и GuestUser.java.AbstractUser.java
package com.howtodoinjava.model;
import java.io.Serializable;
import org.apache.commons.lang3.builder.ToStringBuilder;
public abstract class AbstractUser implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String firstName;
private String lastName;
private String age;
// Setters и getters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public String getAge() { return age; }
public void setAge(String age) { this.age = age; }
}
WebUser.java
package com.howtodoinjava.model;
import java.util.Date;
public class WebUser extends AbstractUser {
private static final long serialVersionUID = 1L;
private Date lastLoggedIn;
public Date getLastLoggedIn() {
return lastLoggedIn;
}
public void setLastLoggedIn(Date lastLoggedIn) {
this.lastLoggedIn = lastLoggedIn;
}
}
GuestUser.java
package com.howtodoinjava.model;
public class GuestUser extends WebUser {
private static final long serialVersionUID = 1L;
private String location;
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
Различные примеры использования
1. toString() метод в супер классе используют все дочерние классы. Вы можете переопределить метод toString() в классе объекта самого верхнего уровня, т.е. в нашем случае AbstractUser.java. Этот метод используют все дочерние классы, если они не содержат собственную версию метода toString().
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
Приведенный выше метод toString() способен дать всю имеющуюся информацию о текущем классе, он также будет работать и в подклассах, если только подкласс не переопределит метод toString().
Пример использования:
package com.howtodoinjava;
import java.util.Date;
import com.howtodoinjava.model.GuestUser;
public class ToStringDemoUsage {
public static void main(String[] args) {
GuestUser guest = getGuestUser();
System.out.println(guest);
}
public static GuestUser getGuestUser() {
GuestUser user = new GuestUser();
user.setId(100);
user.setFirstName("Lokesh");
user.setLastName("Gupta");
user.setAge("30");
user.setLastLoggedIn(new Date());
user.setLocation("New Delhi");
return user;
}
}
Output:
com.howtodoinjava.model.GuestUser@d1f24bb[location=New Delhi,lastLoggedIn=Fri Nov 28 13:31:05 EET 2025,id=100,firstName=Lokesh,lastName=Gupta,age=30]
Важные замечания:
- Метод reflectionToString() использует рефлексию, что может снижать производительность при частом вызове
- Рефлексия игнорирует поля, помеченные как transient или static
- Будьте осторожны с конфиденциальными данными — они будут выведены в строку
package com.howtodoinjava.style;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang3.builder.ToStringStyle;
public class CustomToStringStyle extends ToStringStyle {
private static final long serialVersionUID = 1L;
@Override
protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
if (value instanceof Date) {
value = new SimpleDateFormat("yyyy-MM-dd").format(value);
}
buffer.append(value);
}
}
Для использования форматирования поместите его в методе так:
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, new CustomToStringStyle());
}
Output:
com.howtodoinjava.model.GuestUser@7910769b[location=New Delhi,lastLoggedIn=2025-11-28,id=100,firstName=Lokesh,lastName=Gupta,age=30]
Встроенные стили:
Apache Commons Lang3 предоставляет несколько готовых стилей форматирования:
- ToStringStyle.DEFAULT_STYLE — стандартный стиль
- ToStringStyle.SHORT_PREFIX_STYLE — краткий вывод с именем класса
- ToStringStyle.NO_FIELD_NAMES_STYLE — без имен полей
- ToStringStyle.MULTI_LINE_STYLE — каждое поле на новой строке
- ToStringStyle.JSON_STYLE — JSON-подобный формат
public class WebUser extends AbstractUser {
// Other code
@Override
public String toString() {
return new ToStringBuilder(this)
.appendSuper(super.toString())
.append("lastLoggedIn", lastLoggedIn)
.toString();
}
}
Output:
com.howtodoinjava.model.WebUser@22aed3a5[id=100,firstName=Lokesh,lastName=Gupta,age=30,lastLoggedIn=2025-11-28]
Метод appendSuper() позволяет включить строковое представление родительского класса, а затем добавить свои специфичные поля. Это особенно полезно в глубоких иерархиях наследования.
4. Использование информации только до определенного уровня иерархии наследования
Предположим в каком то дочернем классе вам необходимо раскрыть поля всех супер классов, вы можете включить информацию, до определенного уровня иерархии наследования следующим путем:
public class GuestUser extends WebUser {
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, new CustomToStringStyle(), true, WebUser.class);
}
}
Output:
com.howtodoinjava.model.GuestUser@18dd7404[location=New Delhi,lastLoggedIn=2025-11-28]
Четвертый параметр (WebUser.class) указывает, до какого класса в иерархии нужно подниматься. В данном случае будут выведены поля только из GuestUser и WebUser, но не из AbstractUser.
5. Выводите только ту информацию, которую хотите
Иногда вы не хотите включить все поля класса в метод ToString(). Тогда вы можете сделать это так:
public abstract class AbstractUser implements Serializable {
// Other code
@Override
public String toString() {
return new ToStringBuilder(this)
.append("firstName", firstName)
.append("lastName", lastName)
.append("age", age)
.toString();
}
}
public class GuestUser extends WebUser {
// Other code
@Override
public String toString() {
return new ToStringBuilder(this)
.appendSuper(super.toString())
.append("location", location)
.toString();
}
}
Output:
com.howtodoinjava.model.GuestUser@6483dae1[firstName=Lokesh,lastName=Gupta,age=30,location=New Delhi]
Этот подход дает максимальный контроль над выводом и позволяет исключить конфиденциальные данные (например, пароли или токены доступа) из строкового представления объекта.Заключение
ToStringBuilder от Apache Commons Lang3 — мощный инструмент для создания информативных строковых представлений объектов. Он позволяет:- Быстро создавать toString() через рефлексию
- Гибко настраивать формат вывода
- Контролировать иерархию наследования
- Выбирать конкретные поля для отображения
Если ты только начинаешь разбираться с методом toString() и хочешь понять фундаментальные правила, начни с базового гайда: |
|---|
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ