how find fields of all member variables contained

2019-04-15 18:11发布

I want to make a GUI using Java in which a user can select a bean, edit its fields, and then add an instance of the created bean to a queue. My question though is about accessing the fields. I have a class MyCompositeObject that inherits from MyParentObject. The MyParentObject is composed of multiple beans, each being composed of more beans. The class MyCompositeObject is also composed of beans. I want to find all accessible fields from MyCompositeObject.

Class MyParentObject
{
    MyObjectOne fieldOne;
    MyObjectTwo fieldTwo;
    String name;
  ...
 }

 Class MyCompositeObject extends MyParentObject
 {
    MyObjectThree fieldThree;
    Integer number;
   ...
 }

 Class MyObjectThree
 {
     boolean aBoolean;
     MyObjectFour fieldFour;
   ...
 }

I have been trying to use the BeanUtils api, but I'm getting stuck trying to get the fields of all the member beans. What I am imagining is a depth first search of all fields that could be accessed from an instance of MyCompositeObject. For example, this would include, but not be limited to, the fields: MyCompositeObject.fieldOne, MyCompositeObject.number, MyCompositeObject.fieldThree.aBoolean.

I realized when I tried:

Fields[] allFields = BeanUtils.getFields(myCompositeObject);

that I was in over my head. My research has so far not turned up any prebuilt methods that could do what I describe. Please let me know of any API methods that can do this or tell me how I can go about building my own. Thanks.

1条回答
干净又极端
2楼-- · 2019-04-15 19:04

It's kind of a pain but you have to go in two dimensions

yourBeanClass.getSuperclass(); (and recursively get all superclasses until Object)

and then you can get the fields of each one

eachClass.getDeclaredFields() NOT getFields so you can get all the private fields

Once you have each field

field.getType() which returns the Class of that field

then of course, you need to go up that dudes superclass chain again to make sure you get ALL the fields of the class including the ones in the superclass

Once you have that chain of classes for that field, you can then get it's fields by repeating the above....yes, the jdk made this fun!!!! I wish to god they had a getAllDeclaredFields method so I didn't have to go up the superclass heirarchy.

IMPORTANT: you need to call field.setAccessible(true) so you can read and write to it when it is a private field by the way!!!

Here is code that gets all the fields for a Class including the superclasses..

private static List<Field> findAllFields(Class<?> metaClass) {
    List<Field[]> fields = new ArrayList<Field[]>();
    findFields(metaClass, fields);

    List<Field> allFields = new ArrayList<Field>();
    for(Field[] f : fields) {
        List<Field> asList = Arrays.asList(f);
        allFields.addAll(asList);
    }
    return allFields;
}

private static void findFields(Class metaClass2, List<Field[]> fields) {
    Class next = metaClass2;
    while(true) {
        Field[] f = next.getDeclaredFields();
        fields.add(f);
        next = next.getSuperclass();
        if(next.equals(Object.class))
            return;
    }
}

later, Dean

查看更多
登录 后发表回答