¿Cómo imprimo mi objeto Java sin obtener “SomeType @ 2f92e0f4”?

Mar 19 2015

Tengo una clase definida de la siguiente manera:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

Intenté imprimir una instancia de mi clase:

System.out.println(myPerson);

pero me dio el siguiente resultado: com.foo.Person@2f92e0f4.

Algo similar sucedió cuando intenté imprimir una matriz de Personobjetos:

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

Tengo la salida: [Lcom.foo.Person;@28a418fc

¿Qué significa esta salida? ¿Cómo cambio esta salida para que contenga el nombre de mi persona? ¿Y cómo imprimo colecciones de mis objetos?

Nota : se trata de una sesión de preguntas y respuestas canónicas sobre este tema.

Respuestas

422 DuncanJones Mar 19 2015 at 15:59

Antecedentes

Todos los objetos Java tienen un toString()método, que se invoca cuando intenta imprimir el objeto.

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

Este método se define en la Objectclase (la superclase de todos los objetos Java). El Object.toString()método devuelve una cadena de aspecto bastante feo, compuesta por el nombre de la clase, un @símbolo y el código hash del objeto en hexadecimal. El código para esto se ve así:

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

Un resultado como, com.foo.MyType@2f92e0f4por tanto, se puede explicar como:

  • com.foo.MyType - el nombre de la clase, es decir, la clase está MyTypeen el paquete com.foo.
  • @ - une la cuerda
  • 2f92e0f4 el código hash del objeto.

El nombre de las clases de matriz se ve un poco diferente, lo que se explica bien en los Javadocs para Class.getName(). Por ejemplo, [Ljava.lang.Stringsignifica:

  • [- una matriz unidimensional (a diferencia de [[o [[[etc.)
  • L - la matriz contiene una clase o interfaz
  • java.lang.String - el tipo de objetos en la matriz

Personalización de la salida

Para imprimir algo diferente cuando llama System.out.println(myObject), debe anular el toString()método en su propia clase. He aquí un ejemplo sencillo:

public class Person {

  private String name;
  
  // constructors and other methods omitted
  
  @Override
  public String toString() {
    return name;
  }
}

Ahora, si imprimimos un Person, vemos su nombre en lugar de com.foo.Person@12345678.

Tenga en cuenta que toString()es solo una forma de convertir un objeto en una cadena. Por lo general, esta salida debe describir completamente su objeto de una manera clara y concisa. Un mejor toString()para nuestra Personclase podría ser:

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

Que imprimir, por ejemplo, Person[name=Henry]. Esa es una pieza de datos realmente útil para depurar / probar.

Si desea enfocarse en un solo aspecto de su objeto o incluir mucho formato de jazz, podría ser mejor definir un método separado en su lugar, por ejemplo String toElegantReport() {...}.


Autogenerar la salida

Muchos IDE ofrecen soporte para la generación automática de un toString()método, según los campos de la clase. Consulte los documentos de Eclipse e IntelliJ , por ejemplo.

Varias bibliotecas populares de Java también ofrecen esta función. Algunos ejemplos incluyen:


Imprimir grupos de objetos

Así que has creado un bonito toString()para tu clase. ¿Qué sucede si esa clase se coloca en una matriz o una colección?

Matrices

Si tiene una matriz de objetos, puede llamar Arrays.toString()para producir una representación simple del contenido de la matriz. Por ejemplo, considere esta matriz de Personobjetos:

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

// Prints: [Fred, Mike]

Nota: esta es una llamada a un método estático llamado toString()en la clase Arrays, que es diferente a lo que hemos estado discutiendo anteriormente.

Si tiene una matriz multidimensional , puede usarla Arrays.deepToString()para lograr el mismo tipo de salida.

Colecciones

La mayoría de las colecciones producirán una salida bonita basada en llamar .toString()a cada elemento.

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

// Prints [Alice, Bob]

Por lo tanto, solo debe asegurarse de que los elementos de su lista definan un bonito toString()como se discutió anteriormente.

61 RohithK Apr 15 2015 at 20:31

Creo que apache proporciona una mejor clase de utilidad que proporciona una función para obtener la cadena

ReflectionToStringBuilder.toString(object)
37 PankajManali Mar 19 2015 at 17:04

Cada clase en Java tiene el toString()método de forma predeterminada, que se llama si le pasa algún objeto de esa clase System.out.println(). De forma predeterminada, esta llamada devuelve el className @ hashcode de ese objeto.

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

Puede anular el método toString de una clase para obtener una salida diferente. Ver este ejemplo

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);
    }
}
16 ketankk Apr 21 2016 at 20:45

En Eclipse, vaya a su clase, haga clic derecho-> fuente-> Generar toString();

Anulará el toString()método e imprimirá el objeto de esa clase.

12 Agam Oct 09 2018 at 19:18

Prefiero usar una función de utilidad que usa GSON para deserializar el objeto Java en una cadena 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);
    }
}
6 Mr.Q Jul 28 2016 at 13:00

En intellij, puede generar automáticamente el método toString presionando alt + inset y luego seleccionando toString () aquí hay una salida para una clase de prueba:

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

Como puede ver, genera un String concatenando, varios atributos de la clase, para primitivas imprimirá sus valores y para tipos de referencia usará su tipo de clase (en este caso al método string de Test2).

6 adn.911 Dec 02 2017 at 23:23

De forma predeterminada, cada objeto en Java tiene el toString()método que genera el ObjectType @ HashCode.

Si desea información más significativa, debe anular el toString()método en su clase.

public class Person {
  private String name;

  // constructor and getter/setter omitted

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

Ahora, cuando imprima el objeto persona que lo usa System.out.prtinln(personObj);, imprimirá el nombre de la persona en lugar del nombre de la clase y el código hash.

En su segundo caso, cuando intenta imprimir la matriz, imprime [Lcom.foo.Person;@28a418fcel tipo de matriz y su código hash.


Si desea imprimir los nombres de las personas, hay muchas formas.

Podría escribir su propia función que itera a cada persona e imprime

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

Puede imprimirlo usando Arrays.toString (). Esto me parece el más simple.

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

Puede imprimirlo de la forma Java 8 (utilizando secuencias y referencia de método).

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

También puede haber otras formas. Espero que esto ayude. :)

4 VikrantKashyap May 06 2016 at 18:22

Si imprime directamente cualquier objeto de Persona, lo hará ClassName@HashCodeal Código.

en su caso com.foo.Person@2f92e0f4se está imprimiendo. Donde Persones una clase a la que pertenece el objeto y 2f92e0f4es el código hash del objeto.

public class Person {
  private String name;

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

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

Ahora, si intentas usar el objeto de Person, se imprimirá el nombre

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
3 YasirShabbirChoudhary Mar 27 2017 at 13:21

Si observa la clase Object (clase principal de todas las clases en Java), la implementación del método toString () es

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

siempre que imprima cualquier objeto en Java, se llamará a toString (). Ahora depende de usted si anula toString (), entonces su método llamará a otra llamada al método de la clase Object.

user9869932 Nov 06 2020 at 00:34

Logré hacer esto usando JacksonSpring 5. Dependiendo del objeto, Jackson podría no funcionar en todos los casos.

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

ObjectMapper mapper = new ObjectMapper();
Staff staff = createStaff();
// pretty print
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(staff);
System.out.println("-------------------------------------------------------------------")
System.out.println(json);
System.out.println("-------------------------------------------------------------------")

la salida sería algo como

-------------------------------------------------------------------
{
  "id" : 1,
  "internalStaffId" : "1",
  "staffCms" : 1,
  "createdAt" : "1",
  "updatedAt" : "1",
  "staffTypeChange" : null,
  "staffOccupationStatus" : null,
  "staffNote" : null
}
-------------------------------------------------------------------

Más ejemplos usando Jackson aquí

Puedes probar GSONtambién. Debería ser algo como esto:

Gson gson = new Gson();
System.out.println(gson.toJson(objectYouWantToPrint).toString());