本文介绍了Java toString - ToStringBuilder不够用;不会遍历的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够遍历整个对象图并记录所有成员字段的所有内容。

I need to be able to traverse through my entire object graph and log all contents of all member fields.

例如:对象A有一个对象B的集合,它有一个对象C的集合,A,B,C上有其他字段,等等。

For example: Object A has a collection of Object B's which has a collection of Object C's and A, B, C have additional fields on them, etc.

Apache Commons 是不够的,因为它不会遍历对象图或输出集合的内容。

Apache Commons ToStringBuilder is not sufficient since it won't traverse down an object graph or output contents of a collection.

有没有人知道另一个会这样做的库还是有一个代码片段可以做到这一点?

Does anyone know of another library that will do this or have a code snippet that does this?

推荐答案

你可以使用 org.apache.commons.lang.builder.ReflectionToStringBuilder 。诀窍是在 ToStringStyle 中,您需要遍历该值。 ToStringStyle 将处理已经处理的值,并且不允许递归。我们走了:

You can traverse the whole tree using org.apache.commons.lang.builder.ReflectionToStringBuilder. The trick is that in ToStringStyle you need to traverse into the value. ToStringStyle will take care of values, already processed, and will not allow recursion. Here we go:

System.out.println(ReflectionToStringBuilder.toString(schema, new RecursiveToStringStyle(5)));

private static class RecursiveToStringStyle extends ToStringStyle {

    private static final int    INFINITE_DEPTH  = -1;

    /**
     * Setting {@link #maxDepth} to 0 will have the same effect as using original {@link #ToStringStyle}: it will
     * print all 1st level values without traversing into them. Setting to 1 will traverse up to 2nd level and so
     * on.
     */
    private int                 maxDepth;

    private int                 depth;

    public RecursiveToStringStyle() {
        this(INFINITE_DEPTH);
    }

    public RecursiveToStringStyle(int maxDepth) {
        setUseShortClassName(true);
        setUseIdentityHashCode(false);

        this.maxDepth = maxDepth;
    }

    @Override
    protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
        if (value.getClass().getName().startsWith("java.lang.")
                    || (maxDepth != INFINITE_DEPTH && depth >= maxDepth)) {
            buffer.append(value);
        }
        else {
            depth++;
            buffer.append(ReflectionToStringBuilder.toString(value, this));
            depth--;
        }
    }

    // another helpful method
    @Override
    protected void appendDetail(StringBuffer buffer, String fieldName, Collection<?> coll) {
         depth++;
         buffer.append(ReflectionToStringBuilder.toString(coll.toArray(), this, true, true));
         depth--;
    }
}

这篇关于Java toString - ToStringBuilder不够用;不会遍历的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 15:55