我一直在尝试创建一个强大的代码,可以打印出任何用于调试的Java类。为此,我使用反射。 为了防止递归定义,例如"布尔包含静态最终布尔值TRUE",我忽略等于其父项的字段。 我只是出于懒惰而使用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;
}
答案 0 :(得分:4)
您可以使用Apache commons-lang ReflectionToStringBuilder https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/ReflectionToStringBuilder.html
答案 1 :(得分:2)
我不认为这会起作用。
忽略“等于其父母”的字段将无效。如果您的A
引用了引用B
的{{1}},该怎么办?
您希望了解周期以及DAG中的共享节点。
迭代A
可能会产生副作用,或者它可能永远不会终止,或者它可能会引发异常。
生成任意图形的可读渲染可能非常困难。
这比手工制作的Iterable
方法慢一个数量级。
但是这样考虑一下。如果这是一个好主意,那么会有高调的第三方库来做这种事情。我们都已经在使用它们了。事实证明,有第三方图书馆,但你很难称之为高调。
顺便说一句,您可以使用JAXB或JSON绑定将POJO呈现为文本。这达到了同样的目的......
最后,你的布尔值示例与布尔类型的静态字段不合适。在显示实例时,您不希望呈现静态字段。