tags:

views:

108

answers:

4

I need to instantiate generic variable like Class>. For example,

Class<? extends List<String>> = ...

Variant 1:

Class<? extends List<String>> clazz = LinkedList.class;

don't work - "Incompatible types".

Variant 2:

Class<? extends List> clazz = LinkedList.class;

work, but in this case List is a raw type - not good.

How to instantiate such variables?

+2  A: 
List<String> myList = new ArrayList<String>();
Class<? extends List<String>> var = (Class<? extends List<String>>)myList.getClass();
JRL
Only by means of creation unnecessary object and using getClass() method?
Alex M
The object really is unnecessary, the cast alone will do.
Michael Borgwardt
Hmm... unnecessary object is needed:Class<? extends List<String>> listClass = (Class<? extends List<T>>) ArrayList.class;compile error - inconvertible types.
Alex M
+3  A: 

You can't do it properly. Either use the raw type or use an unsafe cast.

Bozho
@downvoter - perhaps you didn't grasp that "or use an unsafe cast" is practically what the accepted answer means?
Bozho
+7  A: 

There is not really a point in having Class<List<String>>, since it would be equivalent to Class<List<Integer>> (both being a reference to the raw List due to erasure).

Having said that, if your intention is to represent the List<String> type, this is possible, see TypeLiteral of Google Guice.

TypeLiteral<List<String>> type = new TypeLiteral<List<String>>() {};
System.out.println(type.getType()); //should print List<String>

The mechanism that makes it possible is reflection on static type declarations, in either class definition (class X extends Foo<Y>, Y is available through reflection, it is preserved in the bytecode), method definitions, etc. TypeLiteral uses the former, you may notice that it creates a brand new class, so the net effect is that your type parameter gets preserved. It's a nice workaround when you are really fighting against erasure.

Dimitris Andreou
+1  A: 

You can write:

    class ListString extends java.util.LinkedList<String> { }
    Class<? extends java.util.List<String>> clazz = ListString.class;

However, given what Class represents, there isn't that much point. You are better off avoiding reflection wherever possible.

Tom Hawtin - tackline