Как распечатать мой объект Java без получения "SomeType@2f92e0f4"?
у меня есть класс, определенный следующим образом:
public class Person {
private String name;
// constructor and getter/setter omitted
}
Я попытался напечатать экземпляр моего класса:
System.out.println(myPerson);
но я получил следующий результат: com.foo.Person@2f92e0f4.
аналогичная вещь произошла, когда я попытался напечатать массив Person объекты:
Person[] people = //...
System.out.println(people);
я получил на выходе: [Lcom.foo.Person;@28a418fc
что означает этот вывод? Как изменить этот вывод, чтобы он содержал имя моего человека? И как мне печатать коллекции моих объекты?
Примечание: это предназначено как канонические вопросы и ответы по этой теме.
9 ответов:
фон
все объекты Java имеют
toString()метод, который вызывается при попытке распечатать объект.System.out.println(myObject); // invokes myObject.toString()этот метод определен в
Objectкласс (суперкласс всех объектов Java). ЭлементObject.toString()метод возвращает довольно уродливых строку, состоящую из имени класса, к@и hashcode объекта в шестнадцатеричном. Код для этого выглядит например:// Code of Object.toString() public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }результат такой как
com.foo.MyType@2f92e0f4поэтому можно объяснить так:
com.foo.MyType- имя класса, т. е. классMyTypeв пакетеcom.foo.@- объединяет строку2f92e0f4хэш-код объекта.имя классов массива выглядит немного по-другому, что хорошо объясняется в Javadocs для
Class.getName(). Например,[Ljava.lang.Stringозначает:
[- это одномерный массив (в отличие от[[или[[[etc.)L- массив содержит класс или интерфейсjava.lang.String- тип объектов в массиве
Настройки вывода
чтобы напечатать что-то другое, когда вы называете
System.out.println(myObject)необходимо переопределить thetoString()метод в свой класс. Вот такой простой пример:public class Person { private String name; // constructors and other methods omitted @Override public String toString() { return name; } }теперь, если мы напечатаем
Person, мы видим их имя, а неcom.foo.Person@12345678.имейте в виду, что
toString()это просто один способ преобразования объекта в строку. Обычно этот вывод должен полностью описывать ваш объект в ясной и краткой форме. А лучшеtoString()нашихPersonкласс может быть:@Override public String toString() { return getClass().getSimpleName() + "[name=" + name + "]"; }что бы напечатать, например,
Person[name=Henry]. Это действительно полезная часть данных для отладка / тестирование.если вы хотите сосредоточиться только на одном аспекте вашего объекта или включить много джазового форматирования, вам может быть лучше определить отдельный метод, например
String toElegantReport() {...}.
авто-генерации выходных данных
много IDEs поддержка предложения для автоматического генерирования a
toString()метод, основанный на полях в классе. Ознакомиться с документами затмение и IntelliJ, например.несколько популярных библиотек Java также предлагают эту функцию. Некоторые примеры включают в себя:
@ToStringаннотации Проект Lombok
печать группы объекты
Итак, вы создали хороший
toString()для своего класса. Что произойдет, если этот класс помещается в массив или коллекцию?массивы
если у вас есть массив объектов, вы можете позвонить
Arrays.toString()для получения простого представления содержимого массива. Например, рассмотрим этот массивPersonобъекты:Person[] people = { new Person("Fred"), new Person("Mike") }; System.out.println(Arrays.toString(people)); // Prints: [Fred, Mike]Примечание: это вызов static метод
toString()в Класс матриц, который отличается от того, что мы обсуждали выше.если у вас многомерный массив, вы можете использовать
Arrays.deepToString()для достижения того же рода вывода.коллекции
большинство коллекций будет производить довольно выход на основе вызова
.toString()на каждый элемент.List<Person> people = new ArrayList<>(); people.add(new Person("Alice")); people.add(new Person("Bob")); System.out.println(people); // Prints [Alice, Bob]так что вам просто нужно убедиться, что ваши элементы списка определяют хороший
toString()как обсуждалось выше.
Я думаю, что apache предоставляет лучший класс util, который предоставляет функцию для получения строки
ReflectionToStringBuilder.toString(object)
каждый класс в java имеет
toString()метод в нем по умолчанию, который вызываетсяSystem.out.println()Если вы передаете ему какой-либо объект класса. Когда вы пытаетесь напечатать объект класса, тоSystem.out.println()метод будем называтьtoString()класса, который возвращает className@hashcode этого объекта.{ SomeClass sc = new SomeClass(); // Class @ followed by hashcode of object in Hexadecimal System.out.println(sc); }вы можете переопределить метод toString класса, чтобы получить различные выходные. См. этот пример
class A { String s = "I am just a object"; @Override public String toString() { return s; } } class B { public static void main(String args[]) { A obj = new A(); System.out.println(obj); } }
В Eclipse, Иди в свой класс, Щелкните правой кнопкой мыши- > источник - > создать
toString();Он будет переопределить
toString()способ и будет печатать объект этого класса.
по умолчанию, каждый объект в Java имеет
toString()метод, который выводит ObjectType@HashCode.если вы хотите больше значимой информации, то вам нужно переопределить
toString()метод в вашем классе.public class Person { private String name; // constructor and getter/setter omitted // overridding toString() to print name public String toString(){ return name; } }теперь, когда вы печатаете объект Person с помощью
System.out.prtinln(personObj);он будет печатать имя человека, вместо имени класса и hashCode.во втором случае, когда вы пытаетесь напечатать массив, он печатает
[Lcom.foo.Person;@28a418fcтип массива и это хэш-код.
если вы хотите, чтобы напечатать имена людей, есть много способов.
вы можете написать свою собственную функцию, которая повторяет каждого человека и печатает
void printPersonArray(Person[] persons){ for(Person person: persons){ System.out.println(person); } }вы можете распечатать его с помощью массивов.toString (). Это кажется мне самым простым.
System.out.println(Arrays.toString(persons)); System.out.println(Arrays.deepToString(persons)); // for nested arraysвы можете распечатать его java 8 способом (используя потоки и ссылку на метод).
Arrays.stream(persons).forEach(System.out::println);могут быть и другие способы. Надеюсь, это поможет. :)
если вы непосредственно печатаете любой объект человека, это будет
ClassName@HashCodeв коде.в вашем случае
com.foo.Person@2f92e0f4- это надо напечатать . ГдеPerson- это класс, к которому принадлежит объект и2f92e0f4- это хэш-код объекта.public class Person { private String name; public Person(String name){ this.name = name; } // getter/setter omitted @override public String toString(){ return name; } }теперь, если вы пытаетесь использовать объект
Personзатем он напечатает имяClass Test { public static void main(String... args){ Person obj = new Person("YourName"); System.out.println(obj.toString()); } }
в intellij вы можете автоматически генерировать метод toString, нажав alt + inset, а затем выбрав toString () вот выход для тестового класса:
public class test { int a; char b; String c; Test2 test2; @Override public String toString() { return "test{" + "a=" + a + ", b=" + b + ", c='" + c + '\'' + ", test2=" + test2 + '}'; } }Как вы можете видеть, он генерирует строку путем объединения нескольких атрибутов класса, для примитивов он будет печатать их значения, а для ссылочных типов он будет использовать их тип класса (в данном случае для строкового метода Test2).
Если вы посмотрите на класс объекта (родительский класс всех классов в Java) реализация метода toString () является
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }всякий раз, когда вы печатаете любой объект в Java, то toString() будет вызывать. Теперь это зависит от вас, если вы переопределите toString (), то ваш метод вызовет другой вызов метода класса объекта.
Arrays.deepToString(arrayOfObject)выше функция печати массива объектов различных примитивов.
[[AAAAA, BBBBB], [6, 12], [2003-04-01 00:00:00.0, 2003-10-01 00:00:00.0], [2003-09-30 00:00:00.0, 2004-03-31 00:00:00.0], [Interim, Interim], [2003-09-30, 2004-03-31]];
Comments