如何使用 Java 遍历类的对象及其成员类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17738817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 14:49:57  来源:igfitidea点击:

How to iterate through the objects of a class and its member classes using Java

javareflectionjaxb

提问by VictorCreator

I'm trying to get all the data objects(variables alone, not its functions et al) of one class (objectfactory.java) and also, invoke the methods in itself, that create instances of other classes in the same package, and this way, make a list of all the objects in all the classes in a given package. (to put things in perspective, these are classes created by JAXB).

我试图获取一个类 ( objectfactory.java) 的所有数据对象(单独的变量,而不是它的函数等),并且还调用本身的方法,这些方法在同一包中创建其他类的实例,这样,给定包中所有类中所有对象的列表。(从正确的角度来看,这些是由 JAXB 创建的类)。

That is, what I basically want to do is, iterate through, and make a list of all the data objects of:

也就是说,我基本上想要做的是,遍历并列出以下所有数据对象:

Objectfactory, and then,
- Person
- Name
- Url
- Link
- Personnel

classes.

类。

Here is the objectFactory class:

这是 objectFactory 类:

@XmlRegistry
public class ObjectFactory {

    private final static QName _Given_QNAME = new QName("", "given");
    private final static QName _Email_QNAME = new QName("", "email");
    private final static QName _Family_QNAME = new QName("", "family");

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: schema
     * 
     */
    public ObjectFactory() {
    }
    public Person createPerson() {
        return new Person();
    }

    public Name createName() {
        return new Name();
    }

    public Url createUrl() {
        return new Url();
    }

    public Link createLink() {
        return new Link();
    }

    public Personnel createPersonnel() {
        return new Personnel();
    }

    @XmlElementDecl(namespace = "", name = "given")
    public JAXBElement<String> createGiven(String value) {
        return new JAXBElement<String>(_Given_QNAME, String.class, null, value);
    }
    @XmlElementDecl(namespace = "", name = "email")
    public JAXBElement<String> createEmail(String value) {
        return new JAXBElement<String>(_Email_QNAME, String.class, null, value);
    }

    @XmlElementDecl(namespace = "", name = "family")
    public JAXBElement<String> createFamily(String value) {
        return new JAXBElement<String>(_Family_QNAME, String.class, null, value);
    }

}

I could go directlyonly until the fields and methods in ObjectFactory using Java Reflections.(getDeclaredFields()) etc.

我只能直接使用 Java Reflections.(getDeclaredFields()) 等直到 ObjectFactory 中的字段和方法。

But, for the other classes, I can only manually reach their objects. (For eg, for Class Link)

但是,对于其他类,我只能手动访问它们的对象。(例如,对于类链接)

ObjectFactory factory= new ObjectFactory();
Field[] fields = factory.createLink().getClass().getDeclaredFields();

        Field[] fields1 = factory.createPerson().getClass().getDeclaredFields();

        for (Field f1 : fields1) {
            System.out.println("field name = " + f1.getName()); 
        }

but, I want to do this at runtime for all the classes in objectfactory, and not manually by making calls like "createPerson()".

但是,我想在运行时为 objectfactory 中的所有类执行此操作,而不是通过像“createPerson()”这样的调用手动执行此操作。

I tried doing something like this;

我尝试做这样的事情;

ObjectFactory factory= new ObjectFactory();
  Method[] methods = factory.getClass().getDeclaredMethods();
     for (Method m : methods) {
System.out.println("Class name = " + m.getName()); 
        Field[] subfields = m.getClass().getDeclaredFields();


        for (Field sf : subfields) {
            System.out.println("entities = " + sf.getName()); 
        }
        System.out.println("\n\n");

    }

But this doesn't work.

但这不起作用。

My expected output would be something like this:

我的预期输出将是这样的:

Class name = ObjectFactory
    field name = _Given_QNAME
    field name = _Email_QNAME
    field name = _Family_QNAME

Class name = Person
    field name = Name
    field name = Age
    field name = Sex

Class name = Personnel
    field name = address
 ...

and so on..

等等..

How do I do this?

我该怎么做呢?

采纳答案by xyz

public void getAllClassAndFields() {
    ObjectFactory objectFactory = new ObjectFactory();
    Method[] methods = objectFactory.getClass().getDeclaredMethods();
    for (Method method : methods) {
        try {
            // Check if method have XmlElementDecl annotation
            XmlElementDecl annotation = method.getAnnotation(XmlElementDecl.java);
            if (annotation == null) {
                // Invoke method only if it is not annoatated with XmlElementDecl 
                Object object = method.invoke(objectFactory, new Object[] {});
                System.out.println("Class Name = " + object.getClass().getName());
                printFileds(object);
            }

        } catch (Exception e) {
          // I used Exception to keep it simple, instead use appropriate exception types here 
        } 
    }
}

public static void printFileds(Object obj) {
    Field[] fields = obj.getClass().getFields();
    for (Field field : fields) {
        System.out.println("Field Name = " + field.getName());
    }
}

回答by Seabook

Not sure why do you want to do this?
But try the code below

不知道你为什么要这样做?
但是试试下面的代码

public class RelectionTestCases {
public static final String INDENT = "    ";

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    ObjectFactory factory = new ObjectFactory();

    Field[] fields = ObjectFactory.class.getDeclaredFields();

    // Fields
    System.out.println(ObjectFactory.class.getName());
    for (Field field : fields) {
        System.out.println(INDENT + field.getName());
    }

    // Method
    Method[] methods = ObjectFactory.class.getDeclaredMethods();
    for (Method method : methods) {

        if (method.getReturnType().equals(JAXBElement.class)) {
            continue;
        }

        Object object = method.invoke(factory, null);
        System.out.println(object.getClass().getName());

        Field[] subFields = object.getClass().getDeclaredFields();

        for (Field field : subFields) {
            System.out.println(INDENT + field.getName());
        }
    }
}

}

}