How do I print my Java object without getting "SomeType@2f92e0f4"?
Asked Answered
S

15

414

I have a class defined as follows:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

I tried to print an instance of my class:

System.out.println(myPerson);

but I got the following output: com.foo.Person@2f92e0f4.

A similar thing happened when I tried to print an array of Person objects:

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

I got the output: [Lcom.foo.Person;@28a418fc

What does this output mean? How do I change this output so it contains the name of my person? And how do I print collections of my objects?

Note: this is intended as a canonical Q&A about this subject.

Spinks answered 19/3, 2015 at 8:59 Comment(2)
You can use GSON library to convert object to json and vice versa. Very useful for debugging.Expatriate
See also #27648067Foxglove
S
512

Background

All Java objects have a toString() method, which is invoked when you try to print the object.

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

This method is defined in the Object class (the superclass of all Java objects). The Object.toString() method returns a fairly ugly looking string, composed of the name of the class, an @ symbol and the hashcode of the object in hexadecimal. The code for this looks like:

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

A result such as com.foo.MyType@2f92e0f4 can therefore be explained as:

  • com.foo.MyType - the name of the class, i.e. the class is MyType in the package com.foo.
  • @ - joins the string together
  • 2f92e0f4 the hashcode of the object.

The name of array classes look a little different, which is explained well in the Javadocs for Class.getName(). For instance, [Ljava.lang.String means:

  • [ - an single-dimensional array (as opposed to [[ or [[[ etc.)
  • L - the array contains a class or interface
  • java.lang.String - the type of objects in the array

Customizing the Output

To print something different when you call System.out.println(myObject), you must override the toString() method in your own class. Here's a simple example:

public class Person {

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

Now if we print a Person, we see their name rather than com.foo.Person@12345678.

Bear in mind that toString() is just one way for an object to be converted to a string. Typically this output should fully describe your object in a clear and concise manner. A better toString() for our Person class might be:

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

Which would print, e.g., Person[name=Henry]. That's a really useful piece of data for debugging/testing.

If you want to focus on just one aspect of your object or include a lot of jazzy formatting, you might be better to define a separate method instead, e.g. String toElegantReport() {...}.


Auto-generating the Output

Many IDEs offer support for auto-generating a toString() method, based on the fields in the class. See docs for Eclipse and IntelliJ, for example.

Several popular Java libraries offer this feature as well. Some examples include:


Printing groups of objects

So you've created a nice toString() for your class. What happens if that class is placed into an array or a collection?

Arrays

If you have an array of objects, you can call Arrays.toString() to produce a simple representation of the contents of the array. For instance, consider this array of Person objects:

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

// Prints: [Fred, Mike]

Note: this is a call to a static method called toString() in the Arrays class, which is different to what we've been discussing above.

If you have a multi-dimensional array, you can use Arrays.deepToString() to achieve the same sort of output.

Collections

Most collections will produce a pretty output based on calling .toString() on every element.

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

// Prints [Alice, Bob]

So you just need to ensure your list elements define a nice toString() as discussed above.

Spinks answered 19/3, 2015 at 8:59 Comment(0)
Y
92

I think apache provides a better util class which provides a function to get the string

ReflectionToStringBuilder.toString(object)
Younglove answered 15/4, 2015 at 13:31 Comment(3)
This has the advantage that it doesn't require to edit the class, which is sometimes not possible. However, how can I recursively print nested objects too?Dody
@Dody ReflectionToStringBuilder.toString(input, new RecursiveToStringStyle()); This will print nested objects as wellInstrumentalism
@Dody definitely useful if the class can't be edited and is declared as final, otherwise you can just extend it and implement your custom toString() method.Gripper
M
40

Every class in Java has the toString() method in it by default, which is called if you pass some object of that class to System.out.println(). By default, this call returns the className@hashcode of that object.

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

You can override the toString method of a class to get different output. See this example

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);
    }
}
Mateo answered 19/3, 2015 at 10:4 Comment(1)
This is a well-put and short answer, but to clarify why OP is getting [Lcom.foo.Person;@28a418fc as output: that's the output of toString() method, too, but of the one that is implemented in the class that is generated at runtime for the type Person[], not Person (see https://mcmap.net/q/41339/-why-isn-39-t-there-a-java-lang-array-class-if-a-java-array-is-an-object-shouldn-39-t-it-extend-object).Moist
N
18

In Eclipse, Go to your class, Right click->source->Generate toString();

It will override the toString() method and will print the object of that class.

Nogging answered 21/4, 2016 at 13:45 Comment(0)
D
14

I prefer to use a utility function which uses GSON to de-serialize the Java object into JSON string.

/**
 * 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);
    }
}
Durtschi answered 9/10, 2018 at 12:18 Comment(0)
F
7

In intellij you can auto generate toString method by pressing alt+inset and then selecting toString() here is an out put for a test class:

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

As you can see, it generates a String by concatenating, several attributes of the class, for primitives it will print their values and for reference types it will use their class type (in this case to string method of Test2).

Feliks answered 28/7, 2016 at 6:0 Comment(0)
B
7

By default, every Object in Java has the toString() method which outputs the ObjectType@HashCode.

If you want more meaningfull information then you need to override the toString() method in your class.

public class Person {
  private String name;

  // constructor and getter/setter omitted

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

Now when you print the person object using System.out.prtinln(personObj); it will print the name of the person instead of the classname and hashcode.

In your second case when you are trying to print the array, it prints [Lcom.foo.Person;@28a418fc the Array type and it's hashcode.


If you want to print the person names, there are many ways.

You could write your own function that iterates each person and prints

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

You could print it using Arrays.toString(). This seems the simplest to me.

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

You could print it the java 8 way (using streams and method reference).

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

There might be other ways as well. Hope this helps. :)

Bancroft answered 2/12, 2017 at 16:23 Comment(0)
V
5

If you Directly print any object of Person It will the ClassName@HashCode to the Code.

in your case com.foo.Person@2f92e0f4 is getting printed . Where Person is a class to which object belongs and 2f92e0f4 is hashCode of the Object.

public class Person {
  private String name;

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

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

Now if you try to Use the object of Person then it will print the name

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
Vaden answered 6/5, 2016 at 11:22 Comment(0)
F
4

For a "deep" toString() there is an alternative to the JSON based answers (Jackson, GSON, etc.): ReflectionToStringBuilder from the Apache Commons Lang 3 library, with RecursiveToStringStyle or MultilineRecursiveToStringStyle. Code example:

System.out.println("My object: " +
    ReflectionToStringBuilder.toString(theObject, new RecursiveToStringStyle()));

Output examples:

// RecursiveToStringStyle
Person@7f54[name=Stephen,age=29,smoker=false,job=Job@43cd2[title=Manager]]

// MultilineRecursiveToStringStyle
Person@7f54[
  name=Stephen,
  age=29,
  smoker=false,
  job=Job@43cd2[
    title=Manager
  ]
]
Flyback answered 1/5, 2021 at 22:1 Comment(0)
Z
3

If you look at the Object class (Parent class of all classes in Java) the toString() method implementation is

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

whenever you print any object in Java then toString() will be call. Now it's up to you if you override toString() then your method will call other Object class method call.

Zapateado answered 27/3, 2017 at 6:21 Comment(0)
C
3

I managed to get this done using Jackson in Spring 5. Depending on the object it might not work in all cases.

import com.fasterxml.jackson.databind.ObjectMapper;
    
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(yourObject));

The output would look like:

{
  "id" : 1,
  "fieldOne" : "string"
}

Here are more examples using Jackson.

If you use GSON instead It might look like:

Gson gson = new Gson();
System.out.println(gson.toJson(yourObject));
Carine answered 5/11, 2020 at 17:34 Comment(1)
Gson gson = new Gson(); System.out.println(gson.toJson(yourObject)); You don't need to use toString()Memphian
E
3

Using Lombok @Data annotation on class will provide getter, setter, toString and hashcode. Using Lombok is better as it handles boilerplate code.

Extremity answered 11/11, 2021 at 17:49 Comment(1)
Helpful, additionally you can use @ToString annotation, Data annotation has issues when using relationshipsSow
C
2

If you are using project Lombok you could use the @ToString annotation and generate a standard toString() method without adding boilerplate.

import lombok.ToString;

@ToString
public class LoginDto {
  private String user;
  private String pass;
}
...
System.out.println(loginDto.toString());
// LoginDto([email protected], pass=xxxxx)
Carine answered 21/9, 2021 at 9:23 Comment(0)
O
1

If you don't want to Override the toString() method you can use this,

    public static void printJson(Object o) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(o);
            System.out.println(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

We also need to import, import com.fasterxml.jackson.databind.ObjectMapper;

We can make a Utils method and it will be very handy.

Overrefinement answered 29/3, 2023 at 19:21 Comment(0)
H
0

Just use the @ToString from Lombok project gets the job done

Hasheem answered 11/1 at 5:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.