Действительно ли стоит реализовать toString() для классов сущностей?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Действительно ли стоит реализовать toString() для классов сущностей?

Сообщение Anonymous »

Постоянно рекомендуется переопределять (реализовать) метод toString() класса.
  • В самой документации Java API говорится: «Рекомендуется, чтобы все подклассы переопределяли этот метод».
  • Блох, в Effective Java есть пункт «Всегда переопределять toString». И только дурак противоречит Блоху, верно?
Однако я начинаю сомневаться в этом совете: действительно ли стоит реализовывать toString() для сущностных классов?



Попробую изложить свои рассуждения.
  • Ан Объект entity имеет уникальный идентификатор; он никогда не совпадает с другим объектом, даже если эти два объекта имеют эквивалентные значения атрибутов. То есть (для ненулевого x) к классу сущностей применяется следующий инвариант (по определению):

    Код: Выделить всё

    x.equals(y) == (x == y)
  • Метод toString() возвращает строку, которая «текстуально представляет» свой объект (словами Java API).
  • хорошее представление отражает суть объекта, поэтому, если два представления различны, они являются представлениями разных (неэквивалентных) объектов, и наоборот, если два представления эквивалентны, они являются представлениями эквивалентные объекты. Это предполагает следующий инвариант для хорошего представления (для ненулевых x, y):

    Код: Выделить всё

    x.toString().equals(y.toString()) == x.equals(y)
  • Таким образом, для объектов, которые мы ожидаем

    Код: Выделить всё

    x.toString().equals(y.toString()) == (x == y)
    то есть каждый объект сущности должен иметь уникальное текстовое представление, которое возвращает toString(). Некоторые классы сущностей будут иметь уникальное поле имени или числового идентификатора, поэтому их метод toString() может возвращать представление, включающее это имя или числовой идентификатор. Но в целом метод toString() не имеет доступа к такому полю.
  • Без уникального поля для сущности лучшее, что может сделать toString(), — это включить поле, которое вряд ли будет одинаковым для разных объектов. Но это именно то, что требуется для System.identityHashCode(), что и обеспечивает Object.toString().
  • Таким образом, Object.toString() подходит для объекта сущности, который не имеет элементов данных, но для большинства классов вы захотите включить их в текстовое представление, верно? Фактически, вы захотите включить все из них: если тип имеет (не нулевой) элемент данных x, вы захотите включить в представление x.toString().
  • Но это создает проблему для элементов данных, которые содержат ссылки на другие сущности: то есть, которые являются ассоциациями. Если объект Person имеет элемент данных Person, простая реализация создаст фрагмент генеалогического древа этого человека, а не самого Person. Если существуют двусторонние ассоциации, наивная реализация будет рекурсивно выполняться до тех пор, пока не произойдет переполнение стека. Так может быть, пропустить элементы данных, содержащие ассоциации?
  • Но как насчет типа значения «Брак», имеющего элементы данных «Муж» и «Жена»? Об этих ассоциациях должен сообщать Marriage.toString(). Самый простой способ заставить работать все методы toString() — это Person.toString() сообщать только поля идентификаторов (

    Код: Выделить всё

    Person.name
    или System.identityhashCode(this)) Person.
  • Таким образом, кажется, что предоставленная реализация toString() на самом деле не так уж плоха для классов сущностей. В таком случае зачем его переопределять?


Чтобы конкретизировать, рассмотрим следующий код:

Код: Выделить всё

public final class Person {

public void marry(Person spouse)
{
if (spouse == this) {
throw new IlegalArgumentException(this + " may not marry self");
}
// more...
}

// more...
}
Насколько полезным будет переопределение toString() при отладке исключения IlegalArgumentException, вызванного Person.marry()?

Подробнее здесь: https://stackoverflow.com/questions/489 ... ty-classes
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»