Как привести объект к строке в Java

Допустим есть класс:
class Model { Long id = 0L;}
При попытке создать и вывести в консоль переменную типа Model, мы получим для кого-то неожиданный результат:
Model m = new Model();System.out.println(m);
//Выведет "test.Model@55f96302"
На самом деле, под капотом метод System.out.println() вызывает метод toString() у нашего объекта. Поскольку все объекты, и наш не исключение, наследуют класс Object, то у них у всех есть этот метод toString(), который возвращает имя класса объекта + @ + хэшкод объекта.
Чтобы объекты класса приводились к строкам другим, более адекватным образом, необходимо переопределить метод toString() в своём классе. Например, так:
class Model { Long id = 0L;
@Override public String toString() { return "id: " + id; }}
тогда
Model m = new Model();System.out.println(m);
выведет "id: 0" (без кавычек).

Автоматическое переопределение метода toString()


В нашем примере класс Model имел всего одно поле и написать метод toString для него не составляло труда. Но вообще это довольно рутинная операция, учитывая, что некоторые классы имеют десятки полей.
Все основные среды разработки автоматизируют этот процесс. Например, в Intellij Idea или NetBeans установите курсор в том месте класса, где вы хотите сгенерировать метод toString(), нажмите Alt+Insert и в появившемся меню выберите пункт toString(). Далее выберите какие поля должны попасть в результирующую строку. Подтвердите выбор и среда разработки сгенерирует код.
Код IDE всегда генерируется по стандартному шаблону. Поэтому, если вам нужно какое-то более изящное представление вашего класса в виде строки (такое изредка бывает), то придётся писать этот метод вручную.

Что означают элементы строки "test.Model@55f96302"


Стандартный метод toString() приводит объект к типовой строке, вида "test.Model@55f96302". Такая строка состоит из двух частей: слева от @ и справа от @. Соответственно символ '@' служит простым разделителем и не несёт смысловой нагрузки.
Левая часть может содержать:
  • Полное имя класса: study.Model.
  • Символ [, если это одномерный массив, или [[, если массив двумерный и т.д. За квадратной скобкой следует символ примитива (если массив примитивов): [I -- массив int'ов.
  • Если это массив объектов, переменных интерфейса или перечислений, то за скобкой (скобками) следует символ 'L': [Lstudy.Model; Он не имеет отношения к названию класса/интерфейса, а просто маркирует ссылочный тип.

Правая часть подержит хэшкод объекта. В этом легко убедиться, если выполнить такой код:
Model m = new Model();System.out.println(m);System.out.println(Integer.toHexString(m.hashCode()));
Выведет: study.Model@55f96302 и 55f96302
Поскольку метод hashCode() класса Object возвращает хэшкод объекта в виде десятичного int, то, чтобы убедиться в том, что числа совпадают мы это десятичное число превращаем в строку, отражающую шестнадцатеричный вид этого числа с помощью метода Integer.toHexString().