Note: purely out of curiosity and not for any actual use case.
I'm wondering if there is a way to declare the Class
Class
object with valid type parameters:
Class cc1 = Class.class; //raw type
Class<Class> cc2 = Class.class; //now parameter is raw type
Class<Class<?>> cc3 = Class.class; //compile error: inconvertible types
If Class
and Class<?>
are interchangeable, why are Class<Class>
and Class<Class<?>>
not?
EDIT: the question can be generalized to an issue of nested raw type parameters. For example:
ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>(); //same compile error
EDIT2: I should rephrase the question a little: I know that
Class<?> c = Class.class;
is valid but I'm wondering why Class<Class>
is not the same as Class<Class<?>>
The rule here is that the generic type in the left side must match the generic type in the right side.
Class<?>
means a class of any type.Works because Class of any type can be
Class<Class>
.Do not work because Class.class type is
Class<Class>
which is not of typeClass<Class<?>>
Works because the two expressions match.
Don't match.
Generics have some pretty serious limitations. In this case you can't assign a type to the inner type of
Class<Class>
because you're actually referencing the raw type, not an implementation of the raw type. It will give you a warning, but you have no way to fix that warning.Class<Class<?>>
by itself isn't an inconvertible type, you just can't assign a class directly to it because it doesn't have the typeClass<Class<T>>
, it has the typeClass<T>
.Think of it another way; try
List<List<String>>
. To create that, you need to create a List that takes a List of Strings. This works because lists can contain lists.A Class is more like a primitive than a data object, so I don't think it'd be possible to create a Class that is of type Class of something else.
Edit: your extra question about
ArrayList<ArrayList<?>>
is a more obvious example of the inconvertible type issue you're having withClass<Class<?>>
.It's kind of difficult to see exactly what you're asking (or what you're trying to do).. but you can parametrize without raw types.
As far as your last example is concerned, it makes no sense because it appears you want to make an array list of array lists that hold
?
, but your declaration isn't declaring an array list of array lists that hold?
.Properly written (but still not proper Java) would be:
Which is expected. It doesn't work for the same reason something like the following doesn't work:
Java types aren't proactively inferred (even in an inheritance chain).
If you want to keep the wildcard in there, you're welcome to, though: