Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java get generic type of collection [duplicate]

My project include reflection and i'm currently handling with generic types. I've managed to get the generic type from a List(java.util.List) with:

if(originalField.getGenericType() instanceof ParameterizedType){
    ParameterizedType pt = (ParameterizedType) originalField.getGenericType();
    Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
}

I also have a Collection<String> and it turns out that Collection can NOT be cast to ParameterizedType.

Someone have an idea how to get the String (or whatever type that will be) out of the collection?

I've been reading about java erasure so i'm aware of that, but after getting the generic out of the List, i thought that maybe someone knows another 'trick'.

Thanks.

EDITED: I'm iterating over all of the fields of the class with:

for (Field originalField : someClass.getDeclaredFields())

And then when i'm facing some List<String> Field, with the above code i getting the String as the subClass variable.

like image 774
Gumba Avatar asked Oct 08 '13 16:10

Gumba


2 Answers

Your approach is fine. It should work for both List<String> and Collection<String>. For example see this sample code:

public class Demo {

    List<String> list = new ArrayList<>();
    Collection<String> coll = new ArrayList<>();

    public static void main(String args[]){

        Class<Demo> clazz = Demo.class;
        Field[] fields = clazz.getDeclaredFields();

        for (Field field: fields) {

            Type type = field.getGenericType();

            if (type instanceof ParameterizedType) {

                ParameterizedType pType = (ParameterizedType)type;
                Type[] arr = pType.getActualTypeArguments();

                for (Type tp: arr) {
                    Class<?> clzz = (Class<?>)tp;
                    System.out.println(clzz.getName());
                }
            }
        }
    }
}

this prints out:

java.lang.String
java.lang.String
like image 181
Rohit Jain Avatar answered Oct 18 '22 08:10

Rohit Jain


As far as I know, Java fully erases the type, so the compiled code has no traces of the value you assigned to parameter types. All the parametric types are translated to concrete types, with type castings and things like that

In the code I've seen so far, when a class need to know the value of its generic type, it forces an object of that type (or the class) to be passed as a parameter. Something like:

class A<T> {
    private final Class<T> parameterType;

    public A(Class<T> parCls) {
        parameterType = parCls;
    }

    public A(T tObj) {
        parameterType = tObj.getClass();
    }
}
like image 35
Giulio Franco Avatar answered Oct 18 '22 08:10

Giulio Franco