开发者

Recursively print an objects details

How do I print the开发者_运维知识库 content of an object recursively?


You can print it recursively by overriding toString in all your classes.

If you want to have a method like printObjectRecursively(Object o) you need to dive into reflection, fetch the fields, print their name and content recursively using printObjectRecursively(someField).

Example:

public class Test {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a);
    }
}

class A {
    int i = 5;
    B obj = new B();
    String str = "hello";
    public String toString() {
        return String.format("A: [i: %d, obj: %s, str: %s]", i, obj, str);
    }
}

class B {
    int j = 17;
    public String toString() {
        return String.format("B: [j: %d]", j);
    }
}

Prints:

A: [i: 5, obj: B: [j: 17], str: hello]

A reflection-based recursive print method could be written something like this

private static final List LEAVES = Arrays.asList(
        Boolean.class, Character.class, Byte.class, Short.class,
        Integer.class, Long.class, Float.class, Double.class, Void.class,
        String.class);

public static String toStringRecursive(Object o) throws Exception {

    if (o == null)
        return "null";

    if (LEAVES.contains(o.getClass()))
        return o.toString();

    StringBuilder sb = new StringBuilder();
    sb.append(o.getClass().getSimpleName()).append(": [");
    for (Field f : o.getClass().getDeclaredFields()) {
        if (Modifier.isStatic(f.getModifiers()))
            continue;
        f.setAccessible(true);
        sb.append(f.getName()).append(": ");
        sb.append(toStringRecursive(f.get(o))).append(" ");
    }
    sb.append("]");
    return sb.toString();
}


You can use:

ToStringBuilder.reflectionToString(this);

Apache Common Lang contains ToStringBuilder class. You can define different style with ToStringStyle object.


I've had great success doing this on a casual basis using XStream to dump JSON representations of objects. It recurses down objects and just seems to do what you want it to do most of the time. And it's super lightweight. Example:

private static final XStream jsonXStream = 
    new XStream(new JsonHierarchicalStreamDriver());

public static String toDebugString(Object object) {
    return jsonXStream.toXML(object);  
    // ignore "toXML" name, it's going to be JSON.
}


You should implement the toString method for your classes - it will print the information about the class members - usually using their toString methods. |Then you jut iterate through the collection and call toString of each item


Do you really need print this informations out? Maybe watch during debbuging will be enough?


You are looking for something similar to PHP's var_dump, see if this question is of any help: What is the Java equivalent of PHP var_dump?

Also, have a look at reflection: http://java.sun.com/developer/technicalArticles/ALT/Reflection/


You can override the toString method.

Example:

class foo
{
 int i,j;

 String toString()
 {
 StringBuilder b=new StringBuilder();
 return b.append(i).append(j).toString();
 }
}


Use one of the serialization libraries like Jackson (JSON).

This dumps everything in plain text. If you use a Javascript capable editor to prettify the content, with a bit of luck, you might actually make some sense out of it.

If a lot of the objects are not serializable, you might end up with a lot of readable gibberish which will not help anything, unfortunately,

YMMV


In some cases it is easy to use Gson to print object. But sometimes gson does not work.

Here I just improve aioobe' answer for this case:

  • don't print printed objects (protect from infinite cycles)
  • print collections
  • don't go deeply on few basic types, like BigInteger
    private static final Set<Object> looked = new HashSet<>();

    private static final List LEAVES = Arrays.asList(
            Boolean.class, Character.class, Byte.class, Short.class,
            Integer.class, Long.class, Float.class, Double.class, Void.class,
            String.class, java.math.BigInteger.class, java.math.BigDecimal.class);

    public static void toStringRecursive(Object o, StringBuilder sb) throws Exception {
        if (o == null) {
            sb.append("null");
            return;
        }

        if (looked.contains(o)) return;
        looked.add(o);

        if (LEAVES.contains(o.getClass())) {
            sb.append(o);
            return;
        }

        sb.append(o.getClass().getSimpleName()).append(": [");
        if (o.getClass().isArray()) {
            for (Object x : (Object[]) o) {
                toStringRecursive(x, sb);
            }
        } else if (Iterable.class.isAssignableFrom(o.getClass())) {
            for (Object x : (Iterable) o) {
                toStringRecursive(x, sb);
            }
        } else if (Map.class.isAssignableFrom(o.getClass())) {
            for (Object entry : ((Map)o).entrySet()) {
                toStringRecursive(entry, sb);
            }
        } else {
            for (Field f : o.getClass().getDeclaredFields()) {
                if (Modifier.isStatic(f.getModifiers()))
                    continue;
                f.setAccessible(true);
                sb.append(f.getName()).append(": ");
                toStringRecursive(f.get(o), sb);
                sb.append(" ");
            }
        }
        sb.append("]\n");
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜