Java Reflection – Gets the values of nested objects, lists, and arrays within an object

Java Reflection – Gets the values of nested objects, lists, and arrays within an object … here is a solution to the problem.

Java Reflection – Gets the values of nested objects, lists, and arrays within an object

I’m new to reflection and am trying to create a generic function that will receive the object and parse all fields of type String. , String[] or List<String> Any String, String[] or List<String that exists in a nested object >must also be parsed. Is there any utility that can help me do this? Getting the value from the parent object (User) is simple – use BeanUtils.describe(user); – It gives values in the String parent object instead of String[], List<String> and nested objects. I’m sure I might not be the first to need this feature? Are there any utilities or code that can help me with this?

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

}

Solution

Method Class.getDeclaredFields will give you a set of Fields s to represent each field of the class. You can iterate through these and check Field.getType The type returned. Filtering fields of type List to List<String > trickier – see this post for help.

After the first dynamic lookup of the field you want, you should track the (memory)related Field object for better performance.

Here’s a simple 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 some seconds of your second about finding nested UserDefinedObjects. You can apply recursion to the above policies to search for these.

Related Problems and Solutions