Tarik Tarik - 15 days ago 5
Java Question

What is the difference betwen Collection<?> and Collection<T>

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

Answer

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
    }
}
Comments