Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ToStringBuilder doesn't print contents of nested objects

Tags:

java

I am cuurently using apache commons API (commmons-lang.jar) to print an object values as shown below:

ToStringBuilder.reflectionToString(object,ToStringStyle.MULTI_LINE_STYLE))

But this code does not print value if the object has a getter method which returns another object.

For example I have Person object it has a getter method which returns Address object. Using the above code, it just prints Address object name. I am looking for printing Address object values also. If I a pass person.getAddress() to above code it prints that but I want to see everything when I pass person object.

Any suggestions?

like image 584
goutham Avatar asked Mar 09 '10 22:03

goutham


People also ask

Can we print object in Java?

The print(Object) method of PrintStream Class in Java is used to print the specified Object on the stream. This Object is taken as a parameter. Parameters: This method accepts a mandatory parameter object which is the Object to be printed in the Stream. Return Value: This method do not returns any value.

What is toString method in Java?

The toString method is used to return a string representation of an object. If any object is printed, the toString() method is internally invoked by the java compiler. Else, the user implemented or overridden toString() method is called.


3 Answers

Because it does not generate toString recursively. Either look for another tool, or just implement (or, better, IDE-autogenerate) the Object#toString() for all of them yourself.

For example:

public class Person {
    private String name;
    private Address address;
    // Add/generate ctors, getters and setters.

    public String toString() {
        return String.format("Person[name: %s, %s]", name, address);
    }
}

and

public class Address {
    private String street;
    private String city;
    // Add/generate ctors, getters and setters.

    public String toString() {
        return String.format("Address[street: %s, city: %s]", street, city);
    }
}

this way the

String personString = person.toString();

and

System.out.println(person);

would produce something like

Person[name: goutham, Address[street: Main Street 1, city: New York]]
like image 171
BalusC Avatar answered Nov 15 '22 17:11

BalusC


You can use this method to dump each objects

 public static String dump(Object object) {
    Field[] fields = object.getClass().getDeclaredFields();
    StringBuilder sb = new StringBuilder();
    sb.append(object.getClass().getSimpleName()).append('{');

    boolean firstRound = true;

    for (Field field : fields) {
        if (!firstRound) {
            sb.append(", ");
        }
        firstRound = false;
        field.setAccessible(true);
        try {
            final Object fieldObj = field.get(object);
            final String value;
            if (null == fieldObj) {
                value = "null";
            } else {
                value = fieldObj.toString();
            }
            sb.append(field.getName()).append('=').append('\'')
                    .append(value).append('\'');
        } catch (IllegalAccessException ignore) {
            //this should never happen
        }

    }

    sb.append('}');
    return sb.toString();
}

If there are objects inside the object, pass obj1.obj2 as the argument.

like image 43
Jun Avatar answered Nov 15 '22 19:11

Jun


Since version 3.2 of Apache Commons Lang, you can use a RecursiveToStringStyle to achieve exactly what you want.

Either:

ToStringBuilder.reflectionToString(object, new RecursiveToStringStyle());

or

ToStringBuilder.reflectionToString(object, new MultilineRecursiveToStringStyle());

MultilineRecursiveToStringStyle is available since version 3.4

like image 43
Asa Avatar answered Nov 15 '22 17:11

Asa