基于问题Get all Fields of class hierarchy,我想使用-我想-反射来询问以下内容。假设我有以下课程
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 class ex com.foo.bar
在同一包中,或者在我已经知道的特定包中。
我最初的想法是以某种方式获取所有字段,从字段的类中获取软件包,并以某种方式向下钻取多个级别以获取所需的信息。
非常感谢您的帮助。
谢谢
ps。我正在使用JDK 7
答案 0 :(得分:2)
这是检查类声明的字段的简单方法:
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()
来删除重复项。
答案 1 :(得分:1)
谢谢大家,我创建了一个可以解决问题的递归函数。功能如下
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());
}
}
}