web-dev-qa-db-fra.com

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 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 eu la sortie: [Lcom.foo.Person;@28a418fc

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

Note: ceci est conçu comme une question-réponse canonique sur ce sujet.

276
Duncan Jones

Contexte

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

_System.out.println(myObject);  // invokes myObject.toString()
_

Cette méthode est définie dans la classe Object (la superclasse de tous les objets Java). La méthode Object.toString() retourne une chaîne plutôt moche, 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 donc être expliqué comme suit:

  • _com.foo.MyType_ - le nom de la classe, c’est-à-dire que la classe est MyType dans le package _com.foo_.
  • _@_ - réunit la chaîne
  • _2f92e0f4_ le hashcode de l'objet.

Le nom des classes de tableau a un aspect légèrement différent, ce qui est bien expliqué dans les Javadocs pour Class.getName() . Par exemple, _[Ljava.lang.String_ signifie:

  • _[_ - un tableau à une dimension (par opposition à _[[_ ou _[[[_ etc.)
  • L - le tableau contient une classe ou une interface
  • _Java.lang.String_ - le type des objets dans le tableau

Personnaliser la sortie

Pour imprimer quelque chose de différent lorsque vous appelez System.out.println(myObject), vous devez remplacer la méthode toString() 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() n’est qu'un n moyen pour qu'un objet soit converti en chaîne. Généralement, cette sortie doit décrire votre objet de manière claire et concise. Une meilleure toString() pour notre classe Person pourrait être:

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

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

Si vous souhaitez vous concentrer sur un seul aspect de votre objet ou inclure de nombreuses mises en forme jazzy, il peut être préférable de définir une méthode séparée à la place, par exemple. String toElegantReport() {...}.


Génération automatique de la sortie

De nombreux IDE proposent la prise en charge de la génération automatique d'une méthode toString(), basée sur les champs de la classe. Voir la documentation pour Eclipse et IntelliJ , par exemple.

Plusieurs bibliothèques Java populaires offrent également cette fonctionnalité. Quelques exemples incluent:


Impression de groupes d'objets

Vous avez donc créé une belle 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 du tableau. 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: il s'agit d'un appel à une méthode statique appelée toString() dans la classe Arrays, ce qui diffère de ce que nous avons décrit précédemment.

Si vous avez un tableau multidimensionnel , vous pouvez utiliser Arrays.deepToString() pour obtenir le même type de sortie.

Des collections

La plupart des collections produiront une belle sortie en appelant .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 les éléments de votre liste définissent une Nice toString() comme indiqué ci-dessus.

364
Duncan Jones

Je pense que Apache fournit une meilleure classe util qui fournit une fonction pour obtenir la chaîne

ReflectionToStringBuilder.toString(object)
45
Rohith K

Chaque classe de Java a par défaut la méthode toString(), qui est appelée si vous transmettez un objet de cette classe à System.out.println(). Par défaut, cet appel 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);
    }
}
30
Pankaj Manali

Dans Eclipse, accédez à votre classe, clic droit-> source-> Générer toString();

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

10
ketankk

Je préfère utiliser une fonction utilitaire qui utilise GSON pour désérialiser l'objet Java en chaîne JSON.

/**
 * This class provides basic/common functionalities to be applied on Java Objects.
 */
public final class ObjectUtils {

    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();

    private ObjectUtils() {
         throw new UnsupportedOperationException("Instantiation of this class is not permitted in case you are using reflection.");
    }

    /**
     * This method is responsible for de-serializing the Java Object into Json String.
     *
     * @param object Object to be de-serialized.
     * @return String
     */
    public static String deserializeObjectToString(final Object object) {
        return GSON.toJson(object);
    }
}
4
Agam

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

Si vous voulez plus d'informations significatives, vous devez redéfinir 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 personne à l'aide de System.out.prtinln(personObj);, le nom de la personne sera imprimé à la place 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 souhaitez imprimer les noms des personnes, vous avez plusieurs possibilités.

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 Arrays.toString (). Cela me semble le plus simple.

 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 les flux et la référence de la méthode).

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

Il pourrait également y avoir d'autres moyens. J'espère que cela t'aides. :)

4
adn.911

Dans intellij, vous pouvez générer automatiquement la méthode toString en appuyant sur alt + insert, 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 constater, il génère une chaîne en concaténant plusieurs attributs de la classe. Pour les primitives, il imprimera ses valeurs et pour les types de référence, il utilisera son type de classe (dans ce cas, la méthode string de la méthode Test2).

4
Mr.Q

Si vous imprimez directement un objet de Personne, le ClassName@HashCode sera ajouté 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 un 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, il affichera le nom

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
3
Vikrant Kashyap

Si vous examinez la classe Object (classe parent de toutes les classes en Java), la méthode toString () est implémentée.

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

chaque fois que vous imprimez un objet dans Java, toString () sera appelé. Maintenant, à vous de choisir si vous écrasez toString (), votre méthode appellera un autre appel de méthode de la classe Object.