views:

59

answers:

3

How do you get an instance of java.lang.Class for a generic collection like Collection<SomeObject>?

I'm looking for something like the following:

Class clazz = Collection<SomeObject>.class;
+2  A: 

You can't. Type erasure means that you can't do this this way.

What you can do is:

  1. declare a field of the generic type.
  2. call the reflection API to get a Type. E.g. Field.getGenericType().
  3. Use the Type API to see the parameter.
bmargulies
+1  A: 

At runtime these types are erased. If you take an instance of Collection and call getClass(), you will simply get the Collection class.

There are other reflection APIs to get information about members declared with a type parameter.

Uri
However, if you have a field that does not have the generic type declared at compile time, you won't be able to ever learn the generic type.
Konrad Garus
@Konrad: I'm a little confused, how would a field have a generic type but not be declared at compile time?
Uri
Object obj = new ArrayList<Integer>(); List obj = new ArrayList<Integer>(); - as far as I know, you won't be able to find that obj is an ArrayList<Integer>.
Konrad Garus
+2  A: 

As others said, the types are erased at runtime. You must provide the class object to your method. Assuming all your classes that extend SomeObject have constructors with no parameters, you can create objects using reflection. Example:

public <T extends SomeObject> Collection<T> getObjects(Class<T> clazz) {
    List<T> result = new ArrayList<T>();
    for(int i=0; i<3; i++) {
        try {
            T t = clazz.getConstructor((Class[]) null).newInstance((Object[]) null);
            // do something with t
            result.add(t);
        } catch (Exception e) {
            // handle exception
        }
    }
    return result;
}

If you have a class that extends SomeObject, you can use the method like this:

class ObjA extends SomeObject {
}

Collection<ObjA> collection = getObjects(ObjA.class);
True Soft