Use the Commons Lang
ReflectionToStringBuilder
or
ToStringBuilder
and
ToStringBuilder
to create toString()
methods. The following code is an example of a
toString( )
method, which uses a
reflection builder:
import org.apache.commons.lang.builder.ToStringBuilder; public void toString( ) { ReflectionToStringBuilder.toString( this ); }
Assume that you have an object named
PoliticalCandidate
—a bean that represents
some information about a presidential candidate. This bean has a set
of properties: firstName
,
lastName
, dateOfBirth
,
moneyRaised
, and homeState
.
Example 1-1 shows the
PoliticalCandidate
class using a
ReflectionToStringBuilder
; the getter and setter
methods have been omitted for brevity.
Example 1-1. The PoliticalCandidate class using ReflectionToStringBuilder
import java.math.*; import java.util.*; import org.apache.commons.lang.builder.ReflectionToStringBuilder; public class PoliticalCandidate { private String lastName; private String firstName; private Date dateOfBirth; private BigDecimal moneyRaised; private State homeState; // get/set methods are omitted for brevity... public void toString( ) { ReflectionToStringBuilder.toString( this ); } }
The process of keeping the contents of a toString()
method synchronized with a changing object model becomes
a chore (usually a forgotten one). Commons Lang includes a fairly
simple utility designed to automate this chore using reflection. The
ToStringBuilder
class and its extension,
ReflectionToStringBuilder
,
can condense a large toString( )
method body into
one line of code. Most importantly, the
ReflectionToStringBuilder
reflects any future
changes that are made to the object model. The following code
demonstrates the output of a string
built via reflection:
// Create a State State va = new State( "VA", "Virginia"); // Create a Birth Date Calendar calendar = new GregorianCalendar( ); calendar.set( Calendar.YEAR, 1743 ); calendar.set( Calendar.MONTH, Calendar.APRIL ); calendar.set( Calendar.DAY_OF_MONTH, 13 ); Date dob = calendar.getTime( ); BigDecimal moneyRaised = new BigDecimal( 293829292.93 ); // Create a Political Candidate PoliticalCandidate candidate = new PoliticalCandidate( "Jefferson", "Thomas", dob, moneyRaised, va ); System.out.println( candidate );
Assume that the State
object is another bean using
the same ReflectionToStringBuilder
. The code above
sets the properties of a bean and produces the following output:
com.discursive.jccook.lang.builders.PoliticalCandidate@187aeca [lastName=Jefferson,\firstName=Thomas, dateOfBirth=Sat Apr 13 22:38:42 CST 1743, moneyRaised=\293829292.930000007152557373046875, state=\com.discursive.jccook.lang.builders.State@87816d [abbreviation=VA,name=Virginia]]
Tip
As in other cases in this book, I’ve applied a minimal amount of formatting to the output so that it fits on the printed page. Your results will be the same in terms of content but will be all on one long line.
This is not the most readable piece of information in the world, but
it was automatically generated. Keeping a
toString( )
method up-to-date in an object model
that contains one hundred entities is next to impossible under the
constraints of a deadline and a budget. If your objects have
meaningful toString( )
methods, it will be much
easier to diagnose problems in your application. If you use the
ReflectionToStringBuilder
, you are assured that
the message printed out will be accurate; the alternative is to have
a message that may or may not
be relevant—trusting
developers to keep toString( )
methods updated
manually.
Warning
This utility uses the class AccessibleObject
in
the J2SE reflection package to bypass access modifiers and access
private member variables of an object directly. If your system is
running under a restrictive SecurityManager
, you
may need to alter your configuration to allow Commons Lang to bypass
these security restrictions. Only use this reflection builder if you
are certain that your code will run in an environment without a
restrictive security policy. I use this utility in a system that runs
on a few servers in a known location, but if I were writing a
reusable library, a reflection builder would not be feasible; if
someone were to use my library in an environment with a different
security policy, calling a toString( )
may cause
problems. The relevant permission is the
suppressAccessChecks
permission target of the
java.lang.reflect.ReflectPermission
class.
Get Jakarta Commons Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.