Generic toString Method for Simple Java Beans
I have seen developers writing toString method in each of their bean class. The purpose is to print the bean variables for logging or debugging purposes. I thought of reducing their effort by writing a generic toString method to have in their base bean class. It works for simple bean classes. Its no-brainer you can modify to work for others.
public String toString() {
String lineSeaparator = System.getProperty("line.separator");
StringBuffer buffer = new StringBuffer(lineSeaparator);
buffer.append("|---------");
buffer.append(this.getClass());
buffer.append("---------|");
buffer.append(lineSeaparator);
Method[] methods = this.getClass().getMethods();
if(methods != null && methods.length >0){
Method method = null;
for(int i =0; i< methods.length; i++){
method = methods[i];
if(method.getName().startsWith("get")
&& !method.getName().startsWith("getClass")){
buffer.append
(method.getName().replaceAll("get",""));
buffer.append(" = ");
Object[] params=null;
try {
buffer.append
(method.invoke(this, params));
} catch (Exception e) {
buffer.append(" ");
}
buffer.append(lineSeaparator);
}
}
}
buffer.append("|------------------------|");
buffer.append(lineSeaparator);
return buffer.toString();
}
Any suggestions to improve are welcome.



Does this method print only the variable names or variable names + values?
From the code, I think it prints only variable names. Is it correct?
It prints the values too. We are invoking the getter method using the reflection
method.invoke(this, params)
which returns the value.
Now I get it! :-)
Nice code snippet. But it does not work with boolean properties.
This is how you can add boolean props:
for (int i = 0; i < methods.length; i++) {
method = methods[i];
final String methodName = method.getName();
final boolean isBooleanProp = methodName.startsWith(“is”);
if ((methodName.startsWith(“get”) || isBooleanProp) && !method.getName().startsWith(“getClass”)) {
buffer.append(method.getName().replaceAll(isBooleanProp ? “is” : “get”, “”));
buffer.append(” = “);
Object[] params = null;
try {
buffer.append(method.invoke(this, params));
} catch (Exception e) {
buffer.append(” “);
}
buffer.append(lineSeaparator);
}
}
Hello Thejesh.
I wanted to thank you for this posting as it is very helpful.
As I was implementing it I thought of a possible improvement and would love to know your thoughts. By using java.lang.reflect.Field the logic may become simpler and the code more robust:
.
..
…
Field[] fields = this.getClass().getDeclaredFields();
if (fields != null && fields.length > 0) {
Field field = null;
for (int i =0; i < fields.length; i++) {
field = fields[i];
field.setAccessible(true);
buffer.append(field.getName());
buffer.append(" = ");
try {
buffer.append(field.get(this));
} catch (Exception e) {
buffer.append(" ");
}
buffer.append(lineSeparator);
}
}
…
..
.
This should also take care of all booleans as well.
Thoughts?
Hello Thej
BeanUtils offers a describe API that can convert a bean to readable String format.toString() can be overridden to return as
BeanUtils.describe(this).toString();
Hello
below code more specific
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
try {
BeanInfo info = Introspector.getBeanInfo(this.getClass());
PropertyDescriptor[] props = info.getPropertyDescriptors();
for (int i = 0; i < props.length; i++) {
PropertyDescriptor prop = props[i];
if (!prop.getName().equals("class")) {
String data = prop.getName() + "="
+ prop.getReadMethod().invoke(this, null);
if (i < props.length – 1) {
stringBuffer.append(data + "\n");
}
if (i == props.length – 1) {
stringBuffer.append(data);
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return stringBuffer.toString();
}