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 isMyType
in the packagecom.foo
.@
- joins the string together2f92e0f4
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 interfacejava.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 LangMoreObjects.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
C++ Equivalent of Java'S Instanceof
Should I Actually Remove the Valueeventlistener
How to Make a .Jar Out from an Android Studio Project
How to Run a Command At Terminal from Java Program
How to Create an Executable Jar With Dependencies Using Maven
Cannot Make a Static Reference to the Non-Static Method
How Are Anonymous Inner Classes Used in Java
How to Round Up the Result of Integer Division
How to Use an Existing Database With an Android Application
Firebaselistadapter Not Pushing Individual Items For Chat App - Firebase-Ui 3.1
Firebase Android Listview Not Being Displayed
Android 5.0 - Add Header/Footer to a Recyclerview
Eclipse/Tomcat: Deploy Doesn't Work Any More (Classnotfoundexception)
How to Use Java.Net.Urlconnection to Fire and Handle Http Requests