2012-02-27 1 views
2

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

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

где:

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

Любая библиотека там, чтобы решить эту задачу?

ответ

1

Нет библиотеки. Это называется Reflection в java. Взгляните на Class documentation с помощью этого вы можете сделать:

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

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

+0

Да, отражение, безусловно, правильный ответ здесь. – Zoidberg

+0

Спасибо, да это хороший способ найти поля классов. Но мне также нужно найти значение поля листа. Итак, вопрос: у вас есть объект, имя поля объекта, вложенного на уровне N, - как найти это глубоко вложенное значение поля? – dokondr

+0

Также, если вложенное поле является Map, array или Iterable? Затем вам нужно итератировать все объекты, содержащиеся в этих коллекциях. Итак, как вы видите, для решения этой задачи нужно еще многое сделать ... – dokondr

2

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

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 objec t
  • Нам нужно позаботиться, если мы дважды посетим объект.

Примечание - код довольно некрасиво, надеюсь, это достаточно, чтобы дать вам представление о том

+0

Да, спасибо - хорошая иллюстрация! – dokondr

+0

Тем не менее, мой вопрос остается: мне нужно явно различать Map и Iterable, чтобы итерировать эти коллекции - еще один особый случай. Как узнать, что класс реализует определенный интерфейс, например Map или Iterable? – dokondr

+0

Я пропустил это, потому что: поиск в коллекциях не соответствует требованиям вашего формата. Вы * можете * обманывать с 'get (0)' и 'get (1)' для списков, но ваши потерянные с наборами (мы не можем получить одно значение из набора) –

 Смежные вопросы

  • Нет связанных вопросов^_^