Como imprimo meu objeto Java sem obter “SomeType @ 2f92e0f4”?

Mar 19 2015

Eu tenho uma classe definida da seguinte forma:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

Tentei imprimir uma instância da minha classe:

System.out.println(myPerson);

mas eu tenho o seguinte resultado: com.foo.Person@2f92e0f4.

Algo semelhante aconteceu quando tentei imprimir uma série de Personobjetos:

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

Eu tenho o resultado: [Lcom.foo.Person;@28a418fc

O que significa essa saída? Como altero esta saída para que contenha o nome da minha pessoa? E como faço para imprimir coleções de meus objetos?

Observação : trata-se de uma pergunta e resposta canônica sobre este assunto.

Respostas

422 DuncanJones Mar 19 2015 at 15:59

fundo

Todos os objetos Java possuem um toString()método, que é invocado quando você tenta imprimir o objeto.

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

Este método é definido na Objectclasse (a superclasse de todos os objetos Java). O Object.toString()método retorna uma string de aparência bastante feia, composta do nome da classe, um @símbolo e o código hash do objeto em hexadecimal. O código para isso se parece com:

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

Um resultado como com.foo.MyType@2f92e0f4pode, portanto, ser explicado como:

  • com.foo.MyType - o nome da classe, ou seja, a classe está MyTypeno pacote com.foo.
  • @ - junta a corda
  • 2f92e0f4 o hashcode do objeto.

O nome das classes de array parece um pouco diferente, o que é bem explicado nos Javadocs para Class.getName(). Por exemplo, [Ljava.lang.Stringsignifica:

  • [- uma matriz unidimensional (em oposição a [[ou [[[etc.)
  • L - a matriz contém uma classe ou interface
  • java.lang.String - o tipo de objetos na matriz

Personalizando a saída

Para imprimir algo diferente ao chamar System.out.println(myObject), você deve substituir o toString()método em sua própria classe. Aqui está um exemplo simples:

public class Person {

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

Agora, se imprimirmos um Person, veremos seu nome em vez de com.foo.Person@12345678.

Lembre-se de que essa toString()é apenas uma forma de um objeto ser convertido em string. Normalmente, essa saída deve descrever totalmente seu objeto de maneira clara e concisa. Um melhor toString()para nossa Personclasse pode ser:

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

Que imprimiria, por exemplo Person[name=Henry],. Esse é um dado realmente útil para depuração / teste.

Se você deseja se concentrar em apenas um aspecto do seu objeto ou incluir uma grande formatação jazzística, pode ser melhor definir um método separado, por exemplo String toElegantReport() {...}.


Gerando automaticamente a saída

Muitos IDEs oferecem suporte para a geração automática de um toString()método, com base nos campos da classe. Veja documentos para Eclipse e IntelliJ , por exemplo.

Várias bibliotecas Java populares também oferecem esse recurso. Alguns exemplos incluem:


Impressão de grupos de objetos

Então você criou um bom toString()para sua classe. O que acontece se essa classe for colocada em uma matriz ou coleção?

Arrays

Se você tiver uma matriz de objetos, poderá chamar Arrays.toString()para produzir uma representação simples do conteúdo da matriz. Por exemplo, considere esta matriz de Personobjetos:

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

// Prints: [Fred, Mike]

Observação: esta é uma chamada para um método estático chamado toString()na classe Arrays, que é diferente do que discutimos acima.

Se você tiver uma matriz multidimensional , pode usar Arrays.deepToString()para obter o mesmo tipo de saída.

Coleções

A maioria das coleções produzirá uma saída bonita baseada na chamada .toString()de cada elemento.

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

// Prints [Alice, Bob]

Portanto, você só precisa garantir que os elementos da lista definam um bom, toString()conforme discutido acima.

61 RohithK Apr 15 2015 at 20:31

Eu acho que o apache fornece uma classe de utilitário melhor que fornece uma função para obter a string

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

Cada classe em Java possui o toString()método por padrão, que é chamado se você passar algum objeto dessa classe para System.out.println(). Por padrão, esta chamada retorna o className @ hashcode desse objeto.

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

Você pode substituir o método toString de uma classe para obter uma saída diferente. Veja este exemplo

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

No Eclipse, vá para sua classe, clique com o botão direito-> fonte-> Gerar toString();

Ele substituirá o toString()método e imprimirá o objeto daquela classe.

12 Agam Oct 09 2018 at 19:18

Eu prefiro usar uma função de utilitário que usa GSON para desserializar o objeto Java em uma string 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

No intellij, você pode gerar automaticamente o método toString pressionando alt + inset e, em seguida, selecionando toString (), aqui está uma saída para uma classe de teste:

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 você pode ver, ele gera uma String concatenando vários atributos da classe, para primitivas ele imprimirá seus valores e para tipos de referência usará seu tipo de classe (neste caso para o método string de Test2).

6 adn.911 Dec 02 2017 at 23:23

Por padrão, cada objeto em Java tem o toString()método que produz o ObjectType @ HashCode.

Se você quiser informações mais significativas, precisará substituir o toString()método em sua classe.

public class Person {
  private String name;

  // constructor and getter/setter omitted

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

Agora, quando você imprimir o objeto pessoa, System.out.prtinln(personObj);ele imprimirá o nome da pessoa em vez do nome da classe e do código hash.

Em seu segundo caso, quando você está tentando imprimir o array, ele imprime [Lcom.foo.Person;@28a418fco tipo de Array e seu código hash.


Se você quiser imprimir os nomes das pessoas, existem várias maneiras.

Você pode escrever sua própria função que itera cada pessoa e imprime

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

Você pode imprimi-lo usando Arrays.toString (). Isso parece o mais simples para mim.

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

Você pode imprimi-lo da maneira java 8 (usando fluxos e referência de método).

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

Pode haver outras maneiras também. Espero que isto ajude. :)

4 VikrantKashyap May 06 2016 at 18:22

Se você imprimir diretamente qualquer objeto de Pessoa, isso fará parte ClassName@HashCodedo Código.

no seu caso, com.foo.Person@2f92e0f4está sendo impresso. Onde Personé uma classe à qual o objeto pertence e 2f92e0f4é hashCode do objeto.

public class Person {
  private String name;

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

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

Agora se você tentar usar o objeto de Personentão ele irá imprimir o nome

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

Se você olhar para a classe Object (classe pai de todas as classes em Java), a implementação do método toString () é

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

sempre que você imprimir qualquer objeto em Java, toString () será chamado. Agora é com você se você sobrescrever toString (), então seu método irá chamar outra chamada de método da classe Object.

user9869932 Nov 06 2020 at 00:34

Consegui fazer isso usando Jacksonno Spring 5. Dependendo do objeto, Jackson pode não funcionar em todos os 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("-------------------------------------------------------------------")

a saída seria algo como

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

Mais exemplos usando Jackson aqui

Você GSONtambém pode tentar . Deve ser algo assim:

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