ArrayList<T> vs ArrayList<?>
I know w开发者_开发技巧hat ArrayList<T>
is used for, but when should I use ArrayList<?>
? can you explain with example? thanks.
As far as I've been able to tell, ArrayList<?>
basically tells the compiler:
Yes, I know that there is a generic version of ArrayList available to me, but I really, genuinely don't know what kind of objects I'm expecting to be in this one. So don't give me warnings that I'm not using generics the way I should be.
Update
I just learned that there is a real difference between using Raw Types (ArrayList
) and generics with wildcards (ArrayList<?>
) that goes beyond avoiding compiler warnings. Apparently once you declare something as a Raw type, no generics will work on any methods of that type, even if the generics weren't based on the type you omitted. See here for an example.
So while my original answer was generally correct, I thought it would be important to mention that using ArrayList<?>
instead of ArrayList
is more than just a matter of removing compiler warnings.
http://download.oracle.com/javase/tutorial/java/generics/wildcards.html
Note: It's also possible to specify a lower bound by using the super keyword instead of extends. The code
<? super Animal>
, therefore, would be read as "an unknown type that is a supertype of Animal, possibly Animal itself". You can also specify an unknown type with an unbounded wildcard, which simply looks like<?>
. An unbounded wildcard is essentially the same as saying<? extends Object>
.
ArrayList<?>
indicates a collection of an unknown object, that is, it can be anything. It is possible to read from it, but you cannot write to it.
It sounds something like that:
I am a collection! I can read the unknown, but since I do not know what its type, I cannot add stuff
see this very useful tutorial by Oracle.
Also, I find these slides from an MIT Software Construction class very useful, and this generics tutorial.
Here is a concrete example. Let's say you have a
class Base {}
Then class Extender extends Base{}
Now if you have Collection<Extender> collection
and you want to call it using this method.
public void doSomething(Collection<Base> c){...}
Above will not work or copmpile. What will work is
doSomething(Collection<? extends Base> c)
This basically says that I don't care what type ?
is but it has to extend Base. Now that you get that, it will help you understand what ?
mean. It the same as using <? extends Object>
精彩评论