Question

In Java 6

Class<? extends ArrayList<?>> a = ArrayList.class;

gives and error, but

Class<? extends ArrayList<?>> b = (Class<? extends ArrayList<?>>)ArrayList.class;

gives a warning.

Why is (a) an error? What is it, that Java needs to do in the assignment, if not the cast shown in (b)?

And why isn't ArrayList compatible with ArrayList<?> I know one is "raw" and the other is "generic", but what is it you can do with an ArrayList<?> and not with an ArrayList, or the other way around?

Was it helpful?

Solution

Well, a generic class is by definition not equal to a raw class. What you're trying there hides the issue of instantiation of ArrayLists (the actual lists, not their types).

ArrayList raw = new ArrayList();

will work and will allow any kind of element, objects, primitives, anything. On the other hand,

ArrayList<?> generic = new ArrayList<?>();

won't work since it's unclear, at compile time, what actual elements the list will hold. So, in order to make the list (almost) as broadly usable as the raw one, you could instantiate it like this:

ArrayList<?> generic = new ArrayList<Object>();

(That will only hold actual objects, though, no primitives.)

generic and raw will never be equal type-wise and it won't make sense for them to be equal.

What you can do with generic types instead of raw ones? Well, be safe at compile time. :) The other way around? Use primitives (generic types must inherit from Object which primitives do not).

OTHER TIPS

While it's true that Java's type erasure means that generics are compiled into raw classes, they still mean something at compilation. The whole point of generics is to apply consistent casting at compile time, so it should be no wonder that you can't implicitly cast from Class<ArrayList> to Class<? extends ArrayList<?>> even though they are exactly the same type at runtime.

In other words - you get a compilation error because the whole point of generics in Java is to provide safe implicit "casting" in such cases, and raise a compilation error when there is a generic type mismatch.

Licensed under: CC-BY-SA with attribution
scroll top