首页 > 解决方案 > 获取类的所有字段,包括其他类的字段

问题描述

基于获取类层次结构的所有字段的问题,我想使用反射来询问以下问题。假设我有以下课程

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 类 ex 在同一个包中,要么在com.foo.bar我已经知道的特定包中。

我最初的想法是以某种方式获取所有字段,从字段类中获取包,并以某种方式向下钻取多个级别以获取我需要的信息。

任何帮助是极大的赞赏。

谢谢

附言。我正在使用 JDK 7

标签: javareflection

解决方案


这是检查类声明字段的简单方法:

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+ 版本(仅检查树的 2 个级别):

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's fields 等。

distinct()如果它们可能出现,您可能还需要调用以删除重复项。


推荐阅读