Вот простой способ проверки полей, объявленных классом:
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()
, чтобы удалить дубликаты, если они могут появиться.