Generics aren't covariant. In other words, a Collection<String> is not a Collection<Object>, even though a String is an Object. With the first signature, I wouldn't be able print a List<String> for example.
Generic wildcards assist in the expression of covariance (as in your example) and contravariance. Collection<?> is short for Collection<? extends Object> and means "a collection of some specific, unknown type that is or extends Object". As a consequence, we wouldn't be able to add anything but null to such a collection since we couldn't guarantee the added object's type would be valid.
Here's an example that uses a wildcard to express contravariance:
void populateCollection(Collection<? super Integer> c) {
for (int i = 0; i < 10; i++) {
c.add(i);
}
}
I could pass a Collection<Object>, Collection<Number>, or Collection<Integer> into this method, since it's treated as a consumer of Integers. In your example, the collection is a producer of Objects. See this post for further reading on the distinction between "producers" and "consumers" with respect to wildcarded generic types: What is PECS (Producer Extends Consumer Super)?