11

I know what ArrayList<T> is used for, but when should I use ArrayList<?> ? can you explain with example? thanks.

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • In practice, `>` is almost never used on its own. Wildcards are useful with `extends` and `super`. – trutheality Jul 21 '11 at 17:42
  • 2
    If I recall correctly, ArrayList> is just short for ArrayList extends Object>. So in a sense, > is never used on its own. – emory Jul 21 '11 at 17:53
  • possible duplicate of [Java: Different between List, List>, List, List, and List](http://stackoverflow.com/questions/6231973/java-different-between-list-list-listt-liste-and-listobject) – CoolBeans Jul 21 '11 at 18:50
  • I tried to give you an example that should help you understand. Let me know if you more questions. – Amir Raminfar Jul 21 '11 at 21:29

4 Answers4

14

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.

Community
  • 1
  • 1
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • 3
    there are more differences between raw types and types with wildcard parameters. For example, you can add objects to a raw ArrayList, but not to an `ArrayList>` – newacct Sep 15 '11 at 00:22
  • @newacct: I don't think that's true. While I don't have a Java environment available right now, adding objects to an `ArrayList>` seems to work just fine on the Groovy Console: http://groovyconsole.appspot.com/script/550003 – StriplingWarrior Sep 15 '11 at 14:17
  • 2
    that shouldn't work in Java (producer extends, consumer super). also, you can't even have `new ArrayList>()` in Java, so maybe Groovy is a little different – newacct Sep 15 '11 at 19:50
  • @newacct: I got a chance to play with a Java environment, and it looks like you're right on both counts. Excellent observations. – StriplingWarrior Sep 15 '11 at 23:25
5

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.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
Sam
  • 2,398
  • 4
  • 25
  • 37
  • So, is this a clever way to, at compile time, way a read-only list? But then again, what use would it be because you can't get any data into it?! – Christian Bongiorno Dec 30 '13 at 20:55
5

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

trutheality
  • 23,114
  • 6
  • 54
  • 68
padis
  • 2,314
  • 4
  • 24
  • 30
0

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>

Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
  • As a corollary: If you put Collection super Base> c it would mean only super classes of Base, including Base itself, are accepted? Looking for confirmation – Christian Bongiorno Dec 30 '13 at 20:58