Получить все поля класса, включая те, которые являются другими классами - PullRequest
0 голосов
/ 12 октября 2018

На основе вопроса Получить все поля иерархии классов Я хочу задать следующее, используя, как я полагаю, отражение.Предположим, у меня есть следующий класс

package com.foo.bar

public class Employee{ 

    private String firstName; 

    private String id; 

    private Address address; 

// Getters and Setters follow

}

и адрес класса:

package com.foo.bar

public class Address{ 

    private String street; 

    private String streetNum; 

// Getters and Setters follow

}

Я хочу заполнить список всеми полями всех классов, происходящих из Employee, в форме

  • Employee.firstName
  • Employee.id
  • Employee.Address.street
  • Employee.Address.streetNum

Все интересующие меня классы находятся либо в том же пакете, что и класс Employee ex com.foo.bar, либо в определенных пакетах, о которых я уже знаю.

Мое первоначальное мышление состоит в том, чтобы каким-то образом получить все поля, получить пакеты из класса полей и как-то детализировать несколько уровней, чтобы получить необходимую мне информацию.

Любая помощь очень важнаприветствуется.

Спасибо

пс.Я использую JDK 7

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Спасибо всем, я создал рекурсивную функцию, которая добивается цели.Функция следующая

private void getClassFields(final Class c,final List<String> fields) throws ClassNotFoundException {
    for(Field f : c.getDeclaredFields()){
        if(f.getType().getName().contains("foo.bar")){
            getClassFields(Class.forName(f.getType().getName()),fields);
        }else {
            fields.add(f.getName());
        }
    }
}
0 голосов
/ 12 октября 2018

Вот простой способ проверки полей, объявленных классом:

static Set<Field> getFields(Class<?> cls) {
    Set<Field> set = new HashSet<>();

    for (Field f : cls.getDeclaredFields()) {
        set.add(f);

        //a filter to avoid standard classes. Update accordingly
        if (f.getType().getName().startsWith("com.foo.bar")) {
            set.addAll(getFields(f.getType()));
        }
    }

    return set;
}

И простой вызов:

public static void main(String[] args) {
    Set<Field> all = getFields(Employee.class);
    for (Field f : all) {
        System.out.println(String.format("%s.%s", 
             f.getDeclaringClass().getSimpleName(), f.getName()));
    }
}

С примерами классов вышеприведенный вывод:

Employee.firstName
Employee.address
Address.street
Address.streetNum
Employee.id

И вот эквивалентная версия Java8 + (с проверкой только двух уровней дерева):

Stream.of(Employee.class.getDeclaredFields())
        .flatMap(f -> Stream.concat(Stream.of(f), 
                Stream.of(f.getType().getDeclaredFields())))
        .filter(f -> f.getDeclaringClass()
                      .getPackage()
                      .getName()
                      .startsWith("com.foo.bar"))
        .map(f -> String.format("%s.%s", 
                    f.getDeclaringClass().getSimpleName(), f.getName()))
        .forEach(System.out::println);

Приведенный выше filter используется для ограничения проверяемых классов теми, которые находятся в текущем пакете (изменить соответственно).Без него можно получить поля String и т. Д.

Вы также можете позвонить distinct(), чтобы удалить дубликаты, если они могут появиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...