How to Print My Java Object Without Getting "Sometype@2F92E0F4"

How do I print my Java object without getting SomeType@2f92e0f4?

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:

  • ToStringBuilder from Apache Commons Lang

  • MoreObjects.ToStringHelper from Google Guava

  • @ToString annotation from Project Lombok



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.

Why if i try to print an object i get the name of the class followed by a hexadezimal representation?

This is because in Java, System.out.println() applied on an object calls .toString(). The default of the .toString()-method returns the class name followed by @ followed by the hash representation of the object.

How to print contents of Java object without using getters

You have to override toString()

Normal way

class User {
private String firstName;
private String lastName;

public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

@Override
public String toString(){
return this.firstName + " " + this.lastName;
}
}

Using Apache Commons

class User {
private String firstName;
private String lastName;

public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

@Override
public String toString(){
return new ToStringBuilder(this)
.append("firstName", firstName)
.append("lastName", lastName)
.toString();
}
}

Using Google Guava

class User {
private String firstName;
private String lastName;

public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

@Override
public String toString(){
return MoreObjects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", lastName)
.toString();
}
}

How to print predefined java objects?

Is there any way to print what values going in that object?

You need to write your own method to extract the relevant components of the request objects (using the public getters), appropriately format them, and return the lot as a string. Then call that method on the request object, and pass the resulting string to the logger instead of the request object.

If you need to delve into the private state (using abstraction-smashing reflection), that is more difficult, and you risk having your code break if the implementation details of the request class change.

Tedious. But there isn't a general solution, AFAIK.

(If you use a generic serialization scheme, you are liable to run against the problem that some of the components are either not relevant, or nor serializable, or huge ...)


UPDATE - Actually, it would be advisable to use your custom method like this:

if (log.isInfoEnabled()) {
log.info("Sending request: {}", myFormat(request));
}

If you don't guard the info(...) call, the overhead of formatting will be incurred irrespective of the loggin level.

How to call a value from another class with 3 java classes

Override the toString method of the Author class. Perhaps like so:

public String toString() {
return this.lastName +", "+ this.firstName;
}


Related Topics



Leave a reply



Submit