Comment imprimer mon objet Java sans obtenir "SomeType@2f92e0f4"?


J'ai une classe définie comme suit:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

J'ai essayé d'imprimer une instance de ma classe:

System.out.println(myPerson);

Mais j'ai obtenu la sortie suivante: com.foo.Person@2f92e0f4.

Une chose similaire s'est produite lorsque j'ai essayé d'imprimer un tableau d'objets Person:

Person[] people = //...
System.out.println(people); 

J'ai obtenu la sortie: [Lcom.foo.Person;@28a418fc

Que signifie cette sortie? Comment modifier cette sortie pour qu'elle contienne le nom de ma personne? Et comment imprimer des collections de mes objets?

Note: c'est un canonique de Q&A sur ce sujet.

Author: cricket_007, 2015-03-19

9 answers

Contexte

Tous les objets Java ont une méthode toString(), qui est invoquée lorsque vous essayez d'imprimer l'objet.

System.out.println(myObject);  // invokes myObject.toString()

Cette méthode est définie dans Object classe (la superclasse de tous les objets Java). Le Object.toString() la méthode renvoie une chaîne assez laide, composée du nom de la classe, d'un symbole @ et du hashcode de l'objet en hexadécimal. Le code pour cela ressemble à:

// Code of Object.toString()
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Un résultat tel que com.foo.MyType@2f92e0f4 peut par conséquent être expliqué comme:

  • com.foo.MyType - le nom de la classe, c'est à dire la classe est MyType dans le package com.foo.
  • @ - joint la chaîne ensemble
  • 2f92e0f4 le hashcode de l'objet.

Le nom des classes de tableau est un peu différent, ce qui est bien expliqué dans les Javadocs pour Class.getName(). Par exemple, [Ljava.lang.String signifie:

  • [ - un tableau unidimensionnel (par opposition à [[ ou [[[ etc.)
  • L - le tableau contient une classe ou une interface
  • java.lang.String - le type d'objets dans le tableau

Personnalisation de la Sortie

Pour imprimer quelque chose de différent lorsque vous appelez System.out.println(myObject), vous devez remplacer le toString() méthode dans votre propre classe. Voici un exemple simple:

public class Person {

  private String name;

  // constructors and other methods omitted

  @Override
  public String toString() {
    return name;
  }
}

Maintenant, si nous imprimons un Person, nous voyons leur nom plutôt que com.foo.Person@12345678.

Gardez à l'esprit que toString() est juste un moyen pour qu'un objet soit converti en chaîne de caractères. En règle générale, cette sortie doit décrire complètement votre objet de manière claire et concise. Un meilleur toString() pour notre classe Person pourrait être:

@Override
public String toString() {
  return getClass().getSimpleName() + "[name=" + name + "]";
}

Qui imprimerait, par exemple, Person[name=Henry]. C'est une donnée vraiment utile pour le débogage/test.

Si vous voulez vous concentrer sur un seul aspect de votre objet ou inclure beaucoup de formatage jazzy, vous feriez mieux de définir une méthode distincte à la place, par exemple String toElegantReport() {...}.


Génération automatique du Sortie

De nombreux{[98] }Es offrent une prise en charge de la génération automatique d'une méthode toString(), basée sur les champs de la classe. Voir les documents pour Eclipse et IntelliJ , par exemple.

Plusieurs bibliothèques Java populaires offrent également cette fonctionnalité. Voici quelques exemples:


Impression de groupes d'objets

Vous avez donc créé un joli toString() pour votre classe. Que se passe-t-il si cette classe est placée dans un tableau ou une collection?

Tableaux

Si vous avez un tableau d'objets, vous pouvez appeler Arrays.toString() pour produire une représentation simple du contenu de la matrice. Par exemple, considérons ce tableau d'objets Person:

Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));

// Prints: [Fred, Mike]

Remarque: ceci est un appel à une méthode statique appelée toString() dans la classe Arrays, ce qui est différent de ce que nous avons discuté ci-dessus.

Si vous avez un un tableau multi-dimensionnel, vous pouvez utiliser Arrays.deepToString() pour obtenir le même genre de sortie.

Collections

La plupart des collections produiront une jolie sortie basée sur l'appel de .toString() sur chaque élément.

List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));    
System.out.println(people);

// Prints [Alice, Bob]

Il vous suffit donc de vous assurer que vos éléments de liste définissent un joli toString() comme discuté ci-dessus.

 316
Author: Duncan Jones, 2017-07-10 10:09:34

Je pense qu'apache fournit une meilleure classe util qui fournit une fonction pour obtenir la chaîne

ReflectionToStringBuilder.toString(object)
 35
Author: Rohith K, 2015-04-16 20:29:18

Chaque classe en java a toString() méthode par défaut, qui est appelée par System.out.println() si vous en passer un objet d'une classe à elle. Lorsque vous essayez d'imprimer un objet d'une classe, la méthode System.out.println() appelle toString() de la classe qui renvoie le className@hashcode de cet objet.

{
    SomeClass sc = new SomeClass();
    // Class @ followed by hashcode of object in Hexadecimal
    System.out.println(sc);
}

Vous pouvez remplacer la méthode toString d'une classe pour obtenir une sortie différente. Voir cet exemple

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);
    }
}
 23
Author: Pankaj Manali, 2015-04-22 07:41:10

Dans Eclipse, Allez à votre classe, Cliquez avec le bouton droit- > source- > Générer toString();

Il remplacera la méthode toString() et imprimera l'objet de cette classe.

 8
Author: Ketan Keshri, 2017-10-30 05:29:58

Par défaut, chaque objet en Java a la méthode toString() qui génère le ObjectType@HashCode.

Si vous voulez plus d'informations significatives, vous devez remplacer la méthode toString() dans votre classe.

public class Person {
  private String name;

  // constructor and getter/setter omitted

  // overridding toString() to print name
  public String toString(){
     return name;  
  }
}

Maintenant, lorsque vous imprimez l'objet person en utilisant System.out.prtinln(personObj);, il imprimera le nom de la personne au lieu du nom de classe et du code de hachage.

Dans votre deuxième cas lorsque vous essayez d'imprimer le tableau, il imprime [Lcom.foo.Person;@28a418fc le type de tableau et son hashcode.


Si vous voulez imprimer les noms de personne, il y a plusieurs façons.

Vous pouvez écrire votre propre fonction qui itère chaque personne et imprime

void printPersonArray(Person[] persons){
    for(Person person: persons){
        System.out.println(person);
    }
}

Vous pouvez l'imprimer en utilisant des tableaux.toString (). Ce qui semble le plus simple pour moi.

 System.out.println(Arrays.toString(persons));
 System.out.println(Arrays.deepToString(persons));  // for nested arrays  

Vous pouvez l'imprimer de la manière java 8 (en utilisant des flux et une référence de méthode).

 Arrays.stream(persons).forEach(System.out::println);

Il pourrait également y avoir d'autres moyens. Espérons que cette aide. :)

 4
Author: adn.911, 2018-02-01 07:47:05

Si vous imprimez directement un objet de la Personne, Il sera le ClassName@HashCode au Code.

Dans votre cas, com.foo.Person@2f92e0f4 est en cours d'impression . Où Person est une classe à laquelle appartient l'objet et 2f92e0f4 est le hashCode de l'objet.

public class Person {
  private String name;

  public Person(String name){
  this.name = name;
  }
  // getter/setter omitted

   @override
   public String toString(){
        return name;
   }
}

Maintenant, si vous essayez d'Utiliser l'objet de Person, puis il affichera le nom de

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
 3
Author: Vikrant Kashyap, 2016-05-06 11:22:24

Dans intellij, vous pouvez générer automatiquement la méthode toString en appuyant sur alt + encart, puis en sélectionnant toString () voici une sortie pour une classe de test:

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 +
            '}';
 }
}

Comme vous pouvez le voir, il génère une chaîne en concaténant, plusieurs attributs de la classe, pour les primitives, il imprimera leurs valeurs et pour les types de référence, il utilisera leur type de classe (dans ce cas, à la méthode string de Test2).

 3
Author: NԀƎ, 2016-07-28 06:00:49

Si vous regardez la classe Object (classe parente de toutes les classes en Java), l'implémentation de la méthode toString() est

    public String toString() {
       return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

Chaque fois que vous imprimez un objet en Java, toString() sera appelé. Maintenant, c'est à vous de décider si vous remplacez toString() alors votre méthode appellera un autre appel de méthode de classe d'objet.

 2
Author: Yasir Shabbir Choudhary, 2017-03-27 06:21:35
Arrays.deepToString(arrayOfObject)

Au-dessus de la fonction imprimer un tableau d'objets de différentes primitives.

[[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]];
 -2
Author: Hemant Thorat, 2017-07-07 14:06:07