Как распечатать мой объект 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



что означает этот вывод? Как изменить этот вывод, чтобы он содержал имя моего человека? И как мне печатать коллекции моих объекты?



Примечание: это предназначено как канонические вопросы и ответы по этой теме.

744   9  

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) необходимо переопределить the toString() метод в свой класс. Вот такой простой пример:

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() для своего класса. Что произойдет, если этот класс помещается в массив или коллекцию?

массивы

если у вас есть массив объектов, вы можете позвонить 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

    Ничего не найдено.