1

我一直在尝试创建一个健壮的代码,可以打印出任何 Java 类进行调试。为此,我使用反射。为了防止诸如“布尔包含静态最终布尔真”之类的递归定义,我忽略了等于其父项的字段。我使用 String += 只是出于懒惰。它不一定是有效的。

然而,有没有更好的方法来递归描述具有反射的对象?

public String reflectionShowFields(Object parentObject) {
    String stringData = "";

    for (Field field:parentObject.getClass().getFields()) {
        try {
            Class<?> type = field.getType();
            String typeSimpleName = type.getSimpleName();
            Object fieldValue = field.get(parentObject);
            String fieldName = field.getName();
            if (type.isPrimitive() || type.isEnum() || CharSequence.class.isAssignableFrom(type)) {
                stringData += String.format("%s: %s\n", fieldName, fieldValue);
            } else if (Iterable.class.isAssignableFrom(type)) {
                stringData += String.format(">>> %s[%s]: \n", fieldName, typeSimpleName);
                for (Object item:(Iterable)fieldValue) {
                    stringData += reflectionShowFields(item);
                }
                stringData += String.format("<<< %s[%s]: \n", fieldName, typeSimpleName);
            } else if (!fieldValue.equals(parentObject)) {
                stringData += String.format(">>> %s[%s]: %s \n--------\n", fieldName, typeSimpleName, fieldValue.toString());
                stringData+= reflectionShowFields(fieldValue);
                stringData += String.format("<<< %s[%s]: \n", fieldName, typeSimpleName);
            }
        } catch (IllegalAccessException ignored) {}
    }
    return stringData;
}
4

2 回答 2

4

您可以使用 Apache commons-lang ReflectionToStringBuilder https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/ReflectionToStringBuilder.html

于 2013-02-19T15:48:49.570 回答
2

我认为这行不通。

  • 忽略“与其父母相同”的字段是行不通的。如果你有一个A引用 a 的B那个引用回A.

  • 了解循环以及 DAG 中的共享节点。

  • 迭代一个Iterable可以有副作用,或者它可能永远不会终止,或者它可能会抛出异常。

  • 生成任意图形的可读渲染可能真的很难。

  • 这将比手工构建的toString()方法慢一个数量级。

但是这样想。如果这是一个好主意,那么会有高调的 3rd 方库来做这种事情。我们都已经在使用它们了。事实证明有 3rd-party 库,但你很难称它们为高调。


顺便说一句,您可以使用 JAXB 或 JSON 绑定将 POJO 呈现为文本。这达到了同样的目的......


最后,您的 Boolean 示例具有 Boolean 类型的静态字段并不合适。您不想在显示实例时呈现静态字段。

于 2013-02-19T15:58:17.807 回答