库打印嵌套Java对象的所有公共字段?

时间:2012-02-27 13:17:11

标签: java reflection introspection

我需要打印嵌套Java对象的所有公共字段。这些对象只包含数据,没有方法。在任何级别的对象树(叶节点除外)字段可以是地图,列表,集和数组。叶节点是原始类型。 嵌套字段应打印为以下格式的字符串:

<fieldName1>.<fieldName2>. ... <fieldNameN>==<value>

其中:

<fieldName1> -- root (top level) field name
<fieldNameN> -- N-level field name
<value> -- N-level field value.

那里有任何图书馆来解决这个任务吗?

2 个答案:

答案 0 :(得分:3)

以下示例远未完成 - 它起草了一个解决方案并显示了一些陷阱:

public class Main {
    private static Set<Object> visited = new HashSet<Object>();
    public String s = "abc";
    public int i = 10;
    public Main INSTANCE = this;

public static void main (String[] args) throws Exception
{
   printFields(new Main(), "");
}

    private static void printFields(Object obj, String pre) throws Exception{
      Field[] fields = obj.getClass().getFields();
      for (Field field:fields) {
         String value = "";
         String type = field.getType().toString();

         // handle primitve values
         if (type.equals("int")) {
           value += field.getInt(obj);
         } 

         // handle special types, you may add Wrapper classes
          else if (type.equals("class java.lang.String")) {
           value = field.get(obj).toString();  
         } 

         // handle all object that you want to inspect
          else {
           if (visited.contains(field.get(obj))) {
             // necessary to prevent stack overflow
             value = "CYCLE DETECTED";
           } else {
             // recursing deeper
             visited.add(field.get(obj));
             pre += field.getName() + ".";
             printFields(field.get(obj), pre);
           }
         }     

         System.out.printf("%s%s = %s%n", pre, field.getName(), value);
      }
    }
}
  • 我们在反思API
  • 中找到了所需的一切
  • 我们需要递归来走下对象树
  • 我们需要对基元进行一些特殊处理
  • 我们想要对不可变类型进行一些特殊处理(例如,我们不想递归到String对象
  • 如果我们两次访问一个对象,我们需要注意。

注意 - 代码非常难看,希望,这足以给你一个想法

答案 1 :(得分:1)

无需图书馆。这在java中称为Reflection。使用此功能查看Class documentation,您可以这样做:

for(Field field : YourClass.class.getFields()){
    //Print field info
}

编辑: 您可以通过Field获取getDeclaringClass()的课程。通过执行isPrimitive(),可以检查此类以查看它是否是原始类。如果是,您可以打印该值。如果没有,您可以递归并打印此字段的字段。