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?
java
Ethan Jackson

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?

ScenarioUse ThisReason
You only read from the list, not writeList<? 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

Related Articles