I am mainly a C# developer and I was teaching Data Structures to my friend and they use Java in their University and I saw such an expression in Java:
void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
I haven't seen such a thing in C# so I wonder what's the difference between Collection<T>
and Collection<?>
in Java?
void printCollection(Collection<T> c) {
for (Object e : c) {
System.out.println(e);
}
}
I think it could have been written in the way above too. The guy in the documentation was comparing Collection<Object>
and Collection<T>
though.
Examples are taken from http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Collection<?>
is a collection of unknown type parameter.
As far as the caller is concerned, there is no difference between
void printCollection(Collection<?> c) { ... }
and
<T> void printCollection(Collection<T> c) { ... }
However, the latter allows the implementation to refer to the collection's type parameter and is therefore often preferred.
The former syntax exists because it is not always possible to introduce a type parameter at the proper scope. For instance, consider:
List<Set<?>> sets = new ArrayList<>();
sets.add(new HashSet<String>());
sets.add(new HashSet<Integer>());
If I were to replace ?
by some type parameter T
, all sets in sets
would be restricted to the same component type, i.e. I can no longer put sets having different element types into the same list, as evidenced by the following attempt:
class C<T extends String> {
List<Set<T>> sets = new ArrayList<>();
public C() {
sets.add(new HashSet<String>()); // does not compile
sets.add(new HashSet<Integer>()); // does not compile
}
}