Библиотека для печати всех открытых полей вложенных объектов Java? - PullRequest
2 голосов
/ 27 февраля 2012

Мне нужно распечатать все открытые поля вложенных объектов Java. Эти объекты содержат только данные, без методов. На любом уровне дерева объектов (кроме конечных узлов) полями могут быть Карты, Списки, Наборы и массивы. Листовые узлы являются примитивными типами. Вложенное поле должно быть напечатано в виде строки следующего формата:

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

где:

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

Есть ли какая-нибудь библиотека для решения этой задачи?

Ответы [ 2 ]

3 голосов
/ 27 февраля 2012

Следующий пример далек от завершения - он готовит решение и показывает некоторые подводные камни:

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 голос
/ 27 февраля 2012

Библиотека не требуется. Это называется отражением в Java. Взгляните на документацию к классу , с помощью которой вы можете сделать:

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

Edit: Вы можете получить класс Field, выполнив getDeclaringClass(). Этот класс можно проверить, чтобы увидеть, является ли он примитивом, выполнив isPrimitive(). Если это так, вы можете напечатать значение. Если нет, вы можете заполнить и распечатать поля для этого поля.

...