3

I am new to reflection and trying to create a generalized function which will take in object and parse all the fields that are of type String, String[] or List<String>. Any String, String[] or List<String> that is present in nested object has also to be parsed. Is there any utility which can help me in doing that? Getting the values from parent object (User) was simple - used BeanUtils.describe(user); - it gives the String values in parent object but not String[], List<String> and nested object. I am sure I might not be the first one who needs this feature? Are there any utilities or code which could help me achieve do this?

public class User {
    private String somevalue;
    private String[] thisArray;
    private List<String> thisList;
    private UserDefinedObject myObject;
    .
    .
    .

}
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
Hemant P
  • 143
  • 2
  • 2
  • 8
  • 2
    "I am sure I might not be the first one who needs this feature?" ... And I'm sure I'm not the first person to ask if you **really** need this feature. 'Cos so often people use reflection to do things that **should** be done non-reflectively. – Stephen C Nov 08 '12 at 23:30

1 Answers1

3

The method Class.getDeclaredFields will get you an array of Fields representing each field of the class. You could loop over these and check the type returned by Field.getType. Filtering fields of type List to List<String> is trickier - see this post for help with that.

After doing the first dynamic lookup of the fields you want, you should keep track of (memoize) the relevant Field objects for better performance.

Here's a quick example:

//for each field declared in User,
for (Field field : User.class.getDeclaredFields()) {
    //get the static type of the field
    Class<?> fieldType = field.getType();
    //if it's String,
    if (fieldType == String.class) {
        // save/use field
    }
    //if it's String[],
    else if (fieldType == String[].class) {
        // save/use field
    }
    //if it's List or a subtype of List,
    else if (List.class.isAssignableFrom(fieldType)) {
        //get the type as generic
        ParameterizedType fieldGenericType =
                (ParameterizedType)field.getGenericType();
        //get it's first type parameter
        Class<?> fieldTypeParameterType =
                (Class<?>)fieldGenericType.getActualTypeArguments()[0];
        //if the type parameter is String,
        if (fieldTypeParameterType == String.class) {
            // save/use field
        }
    }
}

Note that I used reference equality (==) instead of isAssignableFrom to match String.class and String[].class since String is final.

Edit: Just noticed your bit about finding nested UserDefinedObjects. You could apply recursion to the above strategy in order to search for those.

Community
  • 1
  • 1
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181