When should I use <T extends Number> vs ? extends Number in Java generics?

When should I use <T extends Number> vs ? extends Number in Java generics?

I'm trying to understand the difference between using a generic type parameter and a wildcard in Java generics.

Consider the following two simple examples:

Example 1:

public static <T extends Number> void print(List<T> list)

Example 2:

public static void print(List<? extends Number> list)

Both allow me to pass in a List, List, etc., and iterate over the elements. But I’m unclear about when would someone prefer to use a wildcard (Example 2 over 1)?

Could someone make this clear to me?

Answer

Maybe I think

When to Use Which?

Scenario Use This Reason
You only read from the list, not write List<? extends Number> (Example 2) More flexible, avoids unnecessary type binding
You need to write to the list or return elements <T extends Number> List<T> (Example 1) Preserves type information, allows safe write operations

example

first case:

public static void printList(List<? extends Number> list) {
    for (Number num : list) {
        System.out.println(num);  //  You can read elements
    }
    // list.add(123); //  Compile error: cannot add, exact type is unknown
}
  • usage
List<Integer> ints = List.of(1, 2, 3);
printList(ints);  //  OK

List<Double> doubles = List.of(1.1, 2.2);
printList(doubles);  //  OK

second case:

public static <T extends Number> void copyList(List<T> source, List<T> destination) {
    for (T item : source) {
        destination.add(item);  //  Safe to write
    }
}
  • usage:
List<Integer> src = new ArrayList<>(List.of(1, 2, 3));
List<Integer> dst = new ArrayList<>();
copyList(src, dst);  //  OK, T is Integer

Enjoyed this question?

Check out more content on our blog or follow us on social media.

Browse more questions