Search code examples
javagenericsnested-generics

How to get the class of a field on a generic object when field is referenced by string name


I have a method that takes an object and a string (the string being the name of a field on the object). So i get the field from the object class and use the field.get(object) to get the value. But I want to cast that value to whatever class the field was defined as. Is there a way to do that cast without needing to use @suppressWarnings("unchecked")?

Here is my code. I shortened it to only use one object, but the original used a list of objects and returns a map with map-keys being the objects' values for the field and map-values being the object.

public static <T1,T2> T2 getFieldValue(T1 obj, String fieldName){
    Field field = null;
    T2 value = null;
    try {
        field = obj.getClass().getField( fieldName );
    } catch ( NoSuchFieldException e ) { ... }
    if ( field != null ){
        try {
            value = (T2)field.get(obj);  // <--- unchecked cast!!!
        } catch ( IllegalAccessException e ) { ... }
    }
    return value;
}

Solution

  • I would recommend passing in an argument for the class of T2 if possible. By passing in the Class<T2> you are able to call the cast method. This method will throw a ClassCastException if the cast is invalid. This will also remove the unchecked warnings messages.

    public static <T1, T2> T2 getFieldValue(T1 obj, String fieldName, Class<T2> cls) {
        Field field = null;
        T2 value = null;
        try {
            field = obj.getClass().getField(fieldName);
        } catch (NoSuchFieldException e) {
        }
        if (field != null) {
            try {
                value = cls.cast(field.get(obj));  // <---  no unchecked cast!!!
            } catch (IllegalAccessException e) {
            } catch (ClassCastException e) {
            }
        }
        return value;
    }