Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取类的所有字段,包括属于其他类的字段_Java_Reflection - Fatal编程技术网

Java 获取类的所有字段,包括属于其他类的字段

Java 获取类的所有字段,包括属于其他类的字段,java,reflection,Java,Reflection,基于这个问题,我想用——我想——反射来问以下问题。让我们假设我有下面的课程 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 Addr

基于这个问题,我想用——我想——反射来问以下问题。让我们假设我有下面的课程

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.Address.streetNum
我感兴趣的所有类要么与Employee class ex
com.foo.bar
在同一个包中,要么在我已经知道的特定包中

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

非常感谢您的帮助

谢谢


另外,我正在使用JDK 7,这里有一种检查类声明字段的简单方法:

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;
}

下面是一个等价的Java8+版本(仅检查树的两个级别):

上面的
过滤器
用于将检查的类限制为当前包中的类(相应更改)。没有它,就会得到
字符串
的字段等


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

谢谢大家,我创建了一个递归函数来实现这一点。函数如下所示

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());
        }
    }
}
private void getClassFields(最终类c,最终列表字段)抛出ClassNotFoundException{
for(字段f:c.getDeclaredFields()){
如果(f.getType().getName()包含(“foo.bar”)){
getClassFields(Class.forName(f.getType().getName()),字段);
}否则{
fields.add(f.getName());
}
}
}

为什么你认为你需要反思?非常不清楚…@SeelenVirtuse当然我可能错了。这是我最初的做法。任何其他方法都是为了什么?你在干什么?@AlexiusDiakogiannis你的计划听起来不错。您被困在哪里?您尝试了什么?@Seelenvirtuose我正在尝试填充我在上面示例中描述的列表。在我的项目中,有数百个类似的实体,其中有几十个字段属于这种情况。我想填充此列表的原因超出了问题的范围。
Employee.firstName
Employee.address
Address.street
Address.streetNum
Employee.id
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);
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());
        }
    }
}