简体   繁体   English

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

[英]Library to print all public fields of nested Java objects?

I need to print all public fields of nested Java objects. 我需要打印嵌套Java对象的所有公共字段。 These objects only contain data, no methods. 这些对象仅包含数据,没有方法。 On any level of object tree (except leaf nodes) fields may be Maps, Lists, Sets and arrays. 在对象树的任何级别(叶节点除外)上,字段都可以是Maps,Lists,Sets和arrays。 Leaf nodes are primitive types. 叶节点是原始类型。 Nested field should be printed as a string of the following format: 嵌套字段应打印为以下格式的字符串:

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

where: 哪里:

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

Any library out there to solve this task? 有没有图书馆来解决这个任务?

The following example is far from being complete - it drafts a solution and shows some pitfalls: 以下示例远远不够完整-它起草了一个解决方案并显示了一些陷阱:

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);
      }
    }
}
  • We find all we need in the reflection API 我们在反射API中找到了所需的一切
  • We need recursion to walk down the object tree 我们需要递归才能遍历对象树
  • We need some special handling for primitives 我们需要对原语进行一些特殊处理
  • We want some special handling for immutable types (eg we don't want to recurse into a String object 我们需要对不可变类型进行一些特殊处理(例如,我们不想递归到String对象中
  • We need to take care if we visit an object twice. 如果我们两次访问对象,则需要小心。

Note - the code is pretty ugly, hope, it's enough to give you an idea 注意-代码非常丑陋,希望可以给您一个想法

No library necessary. 无需图书馆。 This is called Reflection in java. 这在Java中称为反射。 Have a look at the Class documentation using this you can do: 使用以下方法可以查看类文档

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

Edit: You can get the class of a Field by doing getDeclaringClass() . 编辑:您可以通过执行getDeclaringClass()获得Field的类。 This class can be checked to see if it is a primitive by doing isPrimitive() . 可以通过执行isPrimitive()来检查此类是否为原始isPrimitive() If it is you can print the value. 如果是,则可以打印该值。 If not you can recurse and print the fields for this field. 如果没有,您可以递归并打印该字段的字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM