The difference between raw and <?> Types in Generics
ArrayList<?> Just means "any type". In other words, any type of ArrayList can be assigned such a variable. It could be ArrayList<Integers> , ArrayList<JButton> or something else. Using only a wildcard, without the super keyword (followed by a type), you cannot add ADD to the list specified as ArrayList<?> . ArrayList , however, means the old ArrayList ArrayList style, which you can perform all kinds 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 the 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) , the compiler will generate a warning, but it will not stop me from adding String to the list of integers. Way of change:
void insert(List<?> list) { // loop through list, do whatever you like list.add("my string"); // compiler error on this dangerous operation } will prevent me from performing such an operation.
ArrayList list = new ArrayList(); We declare a list of arrays that can accept any type of object.
For instance:
list.add(new Dog()); list.add(new Person()); list.add("Test"); For ArrayList<?> list = new ArrayList();
We declare a list of arrays using generics that can accept any object using a wild card ?
The catch here is that we cannot add elements to this list of arrays.
This code does not even compile:
ArrayList<?> list = new ArrayList(); list.add("test"); Update
I think the only goal? wild card in generics should be combined with the extends keyword.
ArrayList<? extends Animal> list = new ArrayList<Dog>(); In this case, we add any object to the list that extends the Animal object.
or to pass as a parameter to a method.
public void foo(List<?> list) { } In this case, the foo method cannot add objects to the list parameter
ArrayList list = new ArrayList(); This is a non-parameterized container that precedes generic java. Objects read from it should usually be thrown to get what you want.
ArrayList<String> list = new ArrayList<String>(); Here we indicated that the container contains String objects. Casting is not required for reading.
<?> is a wildcard parameter meaning "something", such as String, Integer, etc.
Note that ArrayList<?> list = new ArrayList() is not valid syntax; usually a wildcard will be used for method parameters, etc.
There is no difference in behavior.
The real difference is how the compiler handles them. In the first case, you tell the compiler to "treat this as a raw type" and do not try to do any general static typing. In the second case, you say “consider this as a generic type” ... but that the actual type parameter is “some type that we want to avoid by pointing here”.
And note that the syntax <?> Of wildcards cannot be used where a specific type is required.
@ SJuan76 commented:
"(I think they did not add this function to get the code for creating compilation errors)"
Well, actually you could say that it is. Or rather, they left the old form so that the old (pre-Java 5) code would continue to compile without compilation errors using the Java 5+ compiler.