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.

7 Responses

  1. Veera says:

    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?

  2. Thejesh GN says:

    It prints the values too. We are invoking the getter method using the reflection
    method.invoke(this, params)
    which returns the value.

  3. Veerasundar says:

    Now I get it! :-)

  4. Guido says:

    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);
    }
    }

  5. Bryan says:

    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?

  6. Ram says:

    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();

  7. sunil says:

    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();

    }