Why is using Collection.class illegal?

Generics are invariant.

Object o = "someString"; // FINE!
Class<Object> klazz = String.class; // DOESN'T COMPILE!
// cannot convert from Class<String> to Class<Object>

Depending on what it is that you need, you may be able to use wildcards.

Class<? extends Number> klazz = Integer.class; // FINE!

Or perhaps you need something like this:

Class<List<String>> klazz =
   (Class<List<String>>) new ArrayList<String>().getClass();
// WARNING! Type safety: Unchecked cast from
//   Class<capture#1-of ? extends ArrayList> to Class<List<String>>

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:

What does the following code fragment print?

List <String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());

You might be tempted to say false, but you’d be wrong. It prints true, because all instances of a generic class have the same run-time class, regardless of their actual type parameters.

That is, there’s no such thing as List<String>.class or List<Integer>.class; there’s only List.class.

This is also reflected in the JLS 15.8.2 Class Literals

A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a . and the token class.

Note the omission of any allowance for generic type parameters/arguments. Furthermore,

It is a compile time error if any of the following occur:

  • The named type is a type variable or a parameterized type, or an array whose element type is a type variable or parameterized type.

That is, this also doesn’t compile:

void <T> test() {
    Class<?> klazz = T.class; // DOESN'T COMPILE!
    // Illegal class literal for the type parameter T
}

Basically you can’t use generics with class literals, because it just doesn’t make sense: they’re non-reified.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)