All 15 Generics questions
More in Generics
Advertisement
Java › Generics

What is an unbounded wildcard (List<?>), and when is it more appropriate to use than a bounded generic method with a type parameter <T>?

Intermediate

Answer

List<?> ('list of unknown type') represents a list of SOME specific but unknown type, useful when writing a method that operates on the list generically without needing to know or use its specific element type (like printing every element via toString(), or checking the list's size) -- when the method DOES need to establish a relationship between the wildcard type and something else (like ensuring two parameters share the same element type, or returning a value dependent on the element type), a generic type parameter <T> is required instead, since a wildcard's specific captured type can't be referenced or related to anything else within the method's own signature.
// Unbounded wildcard: fine when the method genuinely doesn't care about the specific type
public static void printAll(List<?> list) {
    for (Object item : list) { System.out.println(item); }  // only Object-level operations needed
}

// Generic type parameter: needed when relating type across parameters/return value
public static <T> void copyFirst(List<T> source, List<T> destination) {
    destination.add(source.get(0));  // T ties source and destination together meaningfully
}
Real-world example A generic logging utility that simply prints every element of any list, regardless of its specific type, uses List<?> since it genuinely has no need to reference or constrain the specific element type, while a separate copy utility needing to guarantee both lists share the same element type uses an explicit <T> type parameter instead.

Common follow-ups: Why can't you call list.add(someObject) on a List<?> reference (besides adding null)?;What's the relationship between List<?> and List<Object> -- are they interchangeable?