Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
    
and ArrayList<?>.class? –  ratchet freak May 26 at 21:47
    
ArrayList<?>.class doesn't compile. –  Florian F May 26 at 21:50

2 Answers 2

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.

share|improve this answer
    
Yes, but an ArrayList<?> is an ArrayList of anything you like, which is the same as a raw ArrayList. I can't think of any operation that is possible with a Class<ArrayList> but not a Class<ArrayList<?>>. –  Florian F May 27 at 19:59
1  
Well ya, but the compiler takes it much more literally. –  Rob Y May 27 at 20:15
    
The whole point of the <?> syntax is to make a distinction between the old collection classes where you need to cast manually to any-type generic collections. If you could cast directly between them you wouldn't need the <?> syntax. This is kind of syntactic salt –  Idan Arye May 27 at 23:06
    
I will accept the answer that the compiler takes it too literally. I changed my mind on <?>, but I still feel ArrayList<Object> SHOULD be equivalent and exchangeable with ArrayList, since they fill the same contract. –  Florian F May 28 at 19:01
    
The generic parameter modifies the signature of the methods, so it's not the same contract. –  Idan Arye May 28 at 19:06

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).

share|improve this answer
    
That makes sense, you can add a String to an ArrayList, but not to an ArrayList<?>, because <?> doesn't mean "anything", but means "something you don't know", i.e. potentially a type not compatible with String. –  Florian F May 28 at 19:05
    
@FlorianF Exactly. In fact, ArrayList<?> a = new ArrayList<String>(); a.add(""); won't even compile. And the problem is not instantiating the list but adding a String to a list of unknown elements. (ArrayList<? super String> a = new ArrayList<String>(); a.add(""); will but that's another matter...) –  jhr May 29 at 17:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.