9

It may be asked somewhere but I could not find it.

Please tell me the exact difference between:

ArrayList list = new ArrayList();

and

ArrayList<?> list = new ArrayList();

I cannot figure out what is the exact difference between these two.

Thanks...

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Chintan Patel
  • 729
  • 3
  • 14
  • 31
  • http://stackoverflow.com/questions/15517611/generic-types-wildcards-vs-variables-of-raw-types – assylias Sep 21 '13 at 03:04
  • possible duplicate of [What's the difference between raw types, unbounded wild cards and using Object in generics](http://stackoverflow.com/questions/7360594/whats-the-difference-between-raw-types-unbounded-wild-cards-and-using-object-i) – Louis Wasserman Sep 21 '13 at 05:18

5 Answers5

7

ArrayList<?> simply means "any type." In other words, any type of ArrayList can be assigned to such variable. That could be ArrayList<Integers>, ArrayList<JButton> or anything else. Using the wildcard alone, without the keyword super (followed by a type), means that you cannot ADD anything to the list defined as ArrayList<?>. ArrayList alone however, means the old style type-less ArrayList which you can do all sorts of operations including add.

List<?> list;
List<Integer> ints = new ArrayList<Integer>();
List<Integer> strings = new ArrayList<Integer>();
list = ints; // valid
list = strings; // valid
list.add("new"); // compile error

UPDATE:

Suppose I have following method:

void insert(List list) {
   // loop through list, do whatever you like
   list.add("my string"); // dangerous operation 
}

Now if I call insert(ints) compiler will generate a warning but will not prevent me of adding a String to a list of integers. Changing method to following:

void insert(List<?> list) {
   // loop through list, do whatever you like
   list.add("my string"); // compiler error on this dangerous operation
}

would prevent me of doing such an operation.

Ean V
  • 5,091
  • 5
  • 31
  • 39
  • 1
    You are right. But what is the difference of behavior between them? If only difference is that we cannot add anything into ArrayList> then in which condition we need it? – Chintan Patel Sep 21 '13 at 02:31
  • 2
    This can be used as read-only lists. Suppose that you need to pass your different lists to a function which only does a read operation on them. Using this syntax you can do so. But if you pass your collections as old type-less collections some illegal operation might be done to your collections. That is what the compiler warns you of if you use generic collections as non-generic. Using > syntax, compiler will protect your lists (see my edit). – Ean V Sep 21 '13 at 02:39
  • 1
    You don't answer to his question. He's asking what's the difference between having a list with wildcard and another one with raw object (no generics) – Enrico Giurin Dec 22 '16 at 16:05
4
ArrayList list = new ArrayList();

We are declaring an array list that can accept any type of objects.

For example:

list.add(new Dog());
list.add(new Person());
list.add("Test");

For ArrayList<?> list = new ArrayList();

We are declaring an array list using generics that can accept any object using the wild card ?

The catch here is that we cannot add elements to that array list.

This code will not even compile:

ArrayList<?> list = new ArrayList();
list.add("test");

Update:

I think the only purpose of the ? wild card in generics is to be coupled by the extends keyword.

ArrayList<? extends Animal> list = new ArrayList<Dog>();

In that case we add any object to list that extends the Animal object

or to be passed to as a parameter to a method.

public void foo(List<?> list) { }

In that case the method foo cannot add objects to the parameter list

Rami
  • 7,162
  • 1
  • 22
  • 19
  • Maybe you should explain what is the meaning of `?` that causes the compilation error (I guess they didn't add the feature just to get some code to produce compilation errors). – SJuan76 Sep 21 '13 at 02:34
  • It's mostly intended for function call signatures. There's a whole complicated subject; PECS. http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) – seand Sep 21 '13 at 02:54
  • within foo() you're not allowed to add objects, right, but you can iterate on the list, i.e. - for(Object object:list){ System.out.println(object); } – Enrico Giurin Dec 22 '16 at 16:13
1
ArrayList list = new ArrayList();

This the non-parameterized container that predates java generics. Objects read out of it usually have to be cast to get what you want.

ArrayList<String> list = new ArrayList<String>();

Here we we specified that the container holds String objects. No casting is needed to read out.

The

<?>

is a wildcard parameter meaning "something" such as String, Integer etc.
Note that ArrayList<?> list = new ArrayList() is invalid syntax; normally the wildcard would be used on method parameters etc.

SJuan76
  • 24,532
  • 6
  • 47
  • 87
seand
  • 5,168
  • 1
  • 24
  • 37
1

There is no difference in the behaviour.

The real difference is in the way that the compiler treats them. In the first case, you are telling the compiler "treat this as a raw type" and don't try to do any generic static typing. In the second case, you are saying "treat this as a generic type" ... but that the actual type parameter is "some type that we want to avoid specifying here".

And note that the <?> wildcard syntax cannot be used where a definite type is required.

@SJuan76 commented:

"(I guess they didn't add the feature just to get some code to produce compilation errors)"

Well, actually you could say that that is that they did. Or more precisely, they left the old form so that old (pre-Java 5) code would continue to compile without compilation errors using a Java 5+ compiler.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Hmmm there is a difference. What about all generic info being stripped from the class, leading to possible binding to different methods. Although I haven't checked if ArrayLust has such methods that could be bound differently. – Bohemian Sep 21 '13 at 03:31
0

ArrayList < ? > means array list of type unknown. it is called a wildcard type.

Using the wild card, the following occurs

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error

Without the wildcard you can add whatever you like to your array

cmd
  • 11,622
  • 7
  • 51
  • 61