Java toString() method

Filed Under: Java

Java toString method is a very useful method and even though you may not know it, I am sure you have used it a lot in your programs.

Java toString method

Java toString method
Let’s first establish why I said earlier that you have used toString method even though you might not know it. Do you agree to use System.out.println(object); for learning and debugging purposes? I have used that a lot in my early days and still use it to debug my code (pre production). If you look at it closely, System.out is instance of PrintStream and it’s toString method is implemented like below.


public void println(Object x) {
    String s = String.valueOf(x);
    synchronized (this) {
        print(s);
        newLine();
    }
}

And String.valueOf() implementation is like this:


public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

So ultimately println() and print() functions are calling objects’ toString() method to get the string representation and then print it. So below two statements will produce same result.


System.out.println(object.toString());

System.out.println(object); 

Now that we agree that it’s being used a lot, let’s start to explore toString method in more detail.

Java Object toString() method

Let’s look at a simple program where we will create a java object and call it’s toString method.


package com.journaldev.string;

public class JavaToString {

	public static void main(String[] args) {
		Data d = new Data(10, "Java");
		System.out.println(d);
	}
}

class Data {
	private int id;
	private String name;
	Data(int a, String b) {
		this.id = a;
		this.name = b;
	}
}

When I run and compile this program, I get output as com.journaldev.string.Data@7a46a697.

Now two questions arise – first is where is toString() method implemented because I don’t see it in Data class? Second is what is this output that has hardly any meaningful information.

We know that java supports inheritance and Object is at the top level of this hierarchy, that is where toString method is implemented. If you look at Object class toString implementation, it’s like this:


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

Now it’s clear why the output is having class name with @ and then some hexadecimal number.

Java toString() method important points

Let’s now look at the Object toString() method javadoc and see what it says.

  1. Java toString method returns a string representation of the object.
  2. The result should be a concise but informative representation that is easy for a person to read.
  3. It is recommended that all subclasses override this method.

Based on above recommendation, we should almost always override toString() method to return useful information about the object. So let’s change our Data class implementation and override it’s toString method.


package com.journaldev.string;

public class JavaToString {

	public static void main(String[] args) {
		Data d = new Data(10, "Java");
		System.out.println(d);
	}
}

class Data {
	private int id;
	private String name;

	Data(int a, String b) {
		this.id = a;
		this.name = b;
	}

	public int getId() {
		return id;
	}

	public String getName() {
		return name;
	}
	
	/**
	 * Returns JSON string with id and name
	 * Implementation can change in future, not to rely to convert object to JSON
	 */
	@Override
	public String toString() {
		return "{\"id\":"+id+", \"name\":\""+name+"\"}";
	}
}

Now when you will run above program, output will be {"id":10, "name":"Java"}. Now this makes more sense to anybody looking at the output.

Important Points for Overriding toString() method

Let’s see some important points you should consider while overriding toString() method.

  1. Always use @Override annotation with it, to avoid any errors or unwanted results because of typos.
  2. Make sure to return only useful data in toString() method, your POJO class may have some sensitive information such as email id, SSN number etc. You should either mask them or avoid them altogether, otherwise they can get printed in production server logs and cause security and data privacy issues.
  3. It’s always a good idea to provide some documentation regarding the output of toString() method. For example, someone should not use my toString() implementation to convert object to JSON string. That’s why I have explicitly added that implementation can change in future.
  4. You should always provide getter methods for the object attributes that are part of toString() method output string. Otherwise a programmer would be forced to parse toString() output to get the desired data because there is no other choice.
  5. It’s always best to provide implementation of toString() method, even though you might think that it’s not required. Think of below code where someone is printing a list of data objects.
    
    List<Data> list = new ArrayList<>();
    list.add(new Data(10, "Java")); list.add(new Data(20, "Python"));
    System.out.println(list);
    

    Which output you would prefer?

    Without toString() implementation:

    
    [com.journaldev.string.Data@7a46a697, com.journaldev.string.Data@5f205aa]
    

    With toString() implementation:

    
    [{"id":10, "name":"Java"}, {"id":20, "name":"Python"}]
    

That’s all for brief roundup on java toString() method.

Reference: API Doc

Comments

  1. gaurav says:

    please can you tell me that what are the enhancements in tostring method in java8 comparison to earlier java version?

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages