I am puzzled by generics. You can declare a field like:
Class<Collection<String>> clazz = ...
It seems logical that you could assign this field with:
Class<Collection<String>> clazz = Collection<String>.class;
However, this generates an error:
Syntax error on token ">", void expected after this token
So it looks like the .class
operator does not work with generics. So I tried:
class A<S> { }
class B extends A<String> { }
Class<A<String>> c = B.class;
Also does not work, generates:
Type mismatch: cannot convert from
Class<Test.StringCollection> to Class<Collection<String>>
Now, I really fail to see why this should not work. I know generic types are not reified, but in both cases it seems to be fully type safe without having access to runtime generic types. Anybody an idea?
Generics are invariant.
Depending on what it is that you need, you may be able to use wildcards.
Or perhaps you need something like this:
As for the non-reified at run-time case, you seem to have a good grasp, but here's a quote anyway, from the Java Tutorials on Generics, The Fine Print: A Generic Class is Shared by All Its Invocations:
That is, there's no such thing as
List<String>.class
orList<Integer>.class
; there's onlyList.class
.This is also reflected in the JLS 15.8.2 Class Literals
Note the omission of any allowance for generic type parameters/arguments. Furthermore,
That is, this also doesn't compile:
Basically you can't use generics with class literals, because it just doesn't make sense: they're non-reified.