Java Override toString() with ToStringBuilder

ToStringBuilder is a utility class provided by apache commons lang library. ToStringBuilder is a utility class provided by apache commons lang library. It provides a consistent and better control over what and how much data, an object should expose using toString() method and in which format. It can also help in removing the code size by eliminating the need of overriding toString() method in child subclasses. It can be used to build some kind of design pattern to make full use of capability provided by it.

To include commons-lang in your project, add following dependency in maven configuration file.

<dependency>
	<groupId>commons-lang</groupId>
	<artifactId>commons-lang</artifactId>
	<version>2.5</version>
</dependency>

In this post, I am giving some examples of sample usage which can be considered best practices for overriding toString() method in classes in your next application.

To demonstrate the various possible usage of ToStringBuilder for building the toString() method in various scenarios, I am taking help of three model classes i.e. AbstractUser.java, WebUser.java and GuestUser.java.

AbstractUser.java

package com.howtodoinjava.model;

import java.io.Serializable;
import org.apache.commons.lang.builder.ToStringBuilder;
import com.howtodoinjava.style.CustomToStringStyle;

public abstract class AbstractUser implements Serializable
{
	private static final long serialVersionUID = 1L;
	
	private int id;
	private String firstName;
	private String lastName;
	private String age;
	
	//Setterss and getters
}

WebUser.java

public class WebUser extends AbstractUser 
{
	private static final long serialVersionUID = 1L;
	private Date lastLoggedIn;

	public Date getLastLoggedIn() {
		return lastLoggedIn;
	}

	public void setLastLoggedIn(Date lastLoggedIn) {
		this.lastLoggedIn = lastLoggedIn;
	}
}

GuestUser.java

public class GuestUser extends WebUser
{
	private static final long serialVersionUID = 1L;
	private String location;

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}
}

Various usage examples

1) toString() method is top most super class used perfectly by all subclasses

You can use override toString() method from Object class once in topmost super class i.e. in our case AbstractUser.java. This method will be usable by all childs classes if they do not gave their own version of toString() method.

@Override 
public String toString() 
{ 
	return ToStringBuilder.reflectionToString(this); 
}

Above method is able to given all available information for a class and its subclasses if toString() not overridden in subclasses.

package com.howtodoinjava;

import java.util.Date;
import com.howtodoinjava.model.GuestUser;
import com.howtodoinjava.model.WebUser;

public class ToStringDemoUsage 
{
	public static void main(String[] args) 
	{
		GuestUser guest = getGuestUser();
		System.out.println(guest);
	}
	
	public static GuestUser getGuestUser()
	{
		GuestUser user = new GuestUser();
		user.setId(100);
		user.setFirstName("Lokesh");
		user.setLastName("Gupta");
		user.setAge("30");
		user.setLastLoggedIn(new Date());
		user.setLocation("New Delhi");
		return user;
	}
}

Output:

com.howtodoinjava.model.GuestUser@d1f24bb[location=New Delhi,lastLoggedIn=Mon Jun 03 13:31:05 IST 2013,id=100,firstName=Lokesh,lastName=Gupta,age=30]

2) Custom formatting of any field type like Date

You can enforce the custom formatting for any field type in toString method, and that is also not tightly coupled with toString() implementation. An example custom formatter is as below:

package com.howtodoinjava.style;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang.builder.ToStringStyle;

public class CustomToStringStyle extends ToStringStyle
{
	private static final long serialVersionUID = 1L;
	protected void appendDetail(StringBuffer buffer, String fieldName, Object value) 
	{
	     if (value instanceof Date) 
	     {
	    	 value = new SimpleDateFormat("yyyy-MM-dd").format(value);
	     }
	     buffer.append(value);
	 }
}

To use this formatter, pass it to the method like this.

@Override 
public String toString() 
{ 
		return ToStringBuilder.reflectionToString(this, new CustomToStringStyle()); 
}

Output:

com.howtodoinjava.model.GuestUser@7910769b[location=New Delhi,lastLoggedIn=2013-06-03,id=100,firstName=Lokesh,lastName=Gupta,age=30]

3) Use information from super class in sub class with easy method call

If you want to override the toString() method in sub class, and you want to add the information retrieved from super class before adding anything to it, do it like this.

public class WebUser extends AbstractUser
{
	//Other code
	
	@Override
	public String toString() 
	{
		return new ToStringBuilder(this)
				.appendSuper(super.toString())
				.append("lastLoggedIn", lastLoggedIn).toString();
	}
}

Output:

com.howtodoinjava.model.GuestUser@22aed3a5[location=New Delhi,lastLoggedIn=2013-06-03,id=100,firstName=Lokesh,lastName=Gupta,age=30,CustomMessage=I have been added additionally]

4) Use information up to only a certain level of inheritance hierarchy

Suppose in any subclass you do need to expose all the fields of all super classes, you can include the information up to a certain level also this way:

public class GuestUser extends WebUser
{
	@Override
	public String toString() 
	{
		return ToStringBuilder.reflectionToString(this,new CustomToStringStyle(),true,WebUser.class);
	}
}

Output:

com.howtodoinjava.model.GuestUser@18dd7404[location=New Delhi,lastLoggedIn=2013-06-03]

5) Include only information which you want

Sometimes you do not want to include all the fields in class in toString method. Well, you have a way to do it here also.

public abstract class AbstractUser implements Serializable
{
	//Other code
	
	@Override
	public String toString() {
		return new ToStringBuilder(this)
				.append("firstName", firstName)
				.append("lastName", lastName)
				.append("age", age).toString();
	}
}

public class GuestUser extends WebUser
{
	//Other code

	@Override
	public String toString() 
	{
		return new ToStringBuilder(this)
		.appendSuper(super.toString())
		.append("location", location).toString();
	}
}

Output:

com.howtodoinjava.model.GuestUser@6483dae1[firstName=Lokesh,lastName=Gupta,age=30,location=New Delhi]

Download the sourcecode of above examples in below given link.

Sourcecode Download

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

3 thoughts on “Java Override toString() with ToStringBuilder”

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.