Search⌘ K
AI Features

Wildcards (? extends / ? super)

Explore how Java generics use wildcards like ? extends and ? super to balance type safety and flexibility. Understand invariance, covariance, and contravariance, and apply the PECS principle to design reusable, robust APIs. This lesson helps you write generic code that handles collections safely for both reading and writing scenarios.

We often assume that because Integer is a subclass of Number, a List<Integer> must be a subtype of List<Number>. However, when we try to pass a list of integers to a method expecting a list of numbers, the compiler rejects it. This can be frustrating, especially when our logic seems perfectly sound. This restriction exists to protect memory safety, but it prevents us from writing reusable code that works across class hierarchies.

To solve this, Java provides wildcards, a powerful syntax that allows us to relax these strict type rules safely, enabling us to write flexible APIs that accept a range of types while preventing runtime errors.

The problem of invariance

In Java, generic types are invariant. This means that for any two distinct types Type1 and Type2, List<Type1> is neither a subtype nor a supertype of List<Type2>, even if Type1 inherits from Type2.

This rule prevents heap pollution. If Java allowed us to treat a List<Integer> as a List<Number>, we could attempt to add a Double to it (since a double is a number). However, the underlying list can only hold integers. By enforcing invariance, the compiler prevents this category of error entirely.

In the ...