What does the upper-bounded wildcard `List<? extends Number>` mean, and what kinds of lists can you assign to it?
answer
- ? extends T = unknown subtype of T
- covariant: List<Integer> fits List<? extends Number>
- read as T, can't add (only null)
- Producer Extends (PECS)
basics
~10 sList<? extends Number> means a list of some unknown type that is Number or a subtype of Number. You can assign a List<Number>, List<Integer>, or List<Double> to it.
solid answer
~40 sAn upper-bounded wildcard `<? extends T>` says: the type argument is some single unknown type that is T or any subtype of T. So `List<? extends Number>` accepts `List<Number>`, `List<Integer>`, `List<Double>`, etc. This makes generics covariant: `Integer` is a subtype of `Number`, and with the wildcard `List<Integer>` becomes assignable to `List<? extends Number>` even though plain `List<Integer>` and `List<Number>` are otherwise unrelated. The wildcard is useful when you only want to read elements as `Number` from a list whose exact element type you don't care about. The trade-off is that you cannot add elements (except null), because the compiler can't know the exact element type behind the wildcard.
go deeper
Knows ? extends Number means "some subtype of Number," and that you can read elements as Number but not add to such a list.
Explains it as covariance, connects it to generics invariance, and states that only null can be added and why.
Frames it with PECS (Producer Extends), reasons about the type-safety hole that invariance prevents, and chooses the wildcard in API signatures to widen callers.
Discusses API design trade-offs (where to place wildcards in a public signature), interaction with type inference and bounded type parameters, and when a bounded type variable beats a wildcard.
## Background: what a generic type is In Java, a *generic type* like `List<E>` is parameterized by a *type argument*. `List<Integer>` is a list whose elements are `Integer`; `List<Number>` is a list whose elements are `Number`. The thing in angle brackets (`Integer`, `Number`) is the type argument. ## The invariance problem Even though `Integer` is a subtype of `Number` (every `Integer` *is a* `Number`), Java generics are **invariant**: `List<Integer>` is **NOT** a subtype of `List<Number>`. You cannot write `List<Number> nums = new ArrayList<Integer>();` — it won't compile. This is deliberate and prevents a hole: if it were allowed, you could do `nums.add(3.14)` (a `Double`, which is a `Number`) into what is really a list of `Integer`, corrupting it. ## What the wildcard `?` is A *wildcard* `?` is an anonymous, unknown type argument. `List<?>` means "a list of some specific but unknown type." An **upper-bounded wildcard** adds a ceiling: `List<? extends Number>` means "a list of some specific but unknown type that is `Number` or a subtype of `Number`." The word `extends` here is reused from inheritance syntax; for interfaces it still reads `extends` (e.g. `? extends Runnable`), never `implements`. ## What it buys you: covariance With the upper bound, the family of types becomes **covariant**: all of `List<Number>`, `List<Integer>`, `List<Double>`, `List<Long>` are subtypes of `List<? extends Number>`. So a method parameter typed `List<? extends Number>` can accept any of them. Covariance means "varies in the same direction as the element subtyping." ## Why you can READ as the bound Behind `List<? extends Number>`, whatever the real element type is, it is guaranteed to be a `Number`. So reading is safe: ```java Number n = list.get(0); // always valid ``` You get out a value typed as the upper bound (`Number`), even though you don't know the exact subtype. ## Why you CANNOT add (read-only for writes) Suppose `list` is `List<? extends Number>`. At runtime it might really be a `List<Integer>` or a `List<Double>`. If you tried `list.add(someInteger)`, the compiler can't prove the real list accepts `Integer` — it might be a `List<Double>`. To stay safe, the compiler rejects **all** `add(x)` calls for any non-null `x`. The single exception is `list.add(null)`, because `null` is a member of every reference type. This is why an upper-bounded wildcard collection is effectively read-only for additions — it acts as a **producer** (a source you read from), not a **consumer** (a sink you write to). ## The PECS mnemonic Joshua Bloch's rule: **PECS = Producer Extends, Consumer Super.** If a parameter only *produces* (you read T out of it), use `<? extends T>`. If it only *consumes* (you write T into it), use `<? super T>` (a lower-bounded wildcard). `<? extends T>` is the producer side. ## Quick contrast table | Declaration | Can read as | Can add | |---|---|---| | `List<Number>` | `Number` | any `Number` | | `List<? extends Number>` | `Number` | only `null` | | `List<?>` | `Object` | only `null` | Upper-bounded wildcards let an API say "give me any list of Numbers and I'll only read from it," maximizing the set of callers that can use the method while keeping it type-safe.
- Why can't you add an Integer to a `List<? extends Number>`?Because the actual list could be a `List<Double>` or `List<Long>`; the compiler can't prove an `Integer` is acceptable, so it rejects all adds except `null`.
- Can you use `extends` with an interface, e.g. `? extends Comparable`?Yes. In wildcard bounds and type-parameter bounds, `extends` is used for both classes and interfaces; `implements` is never used here.
saying these in an interview costs you the question
- Saying `List<? extends Number>` is the same as `List<Number>` — it isn't; the wildcard one can't accept adds.
- Thinking you can add an `Integer` to a `List<? extends Number>`.
- Believing `List<Integer>` is a subtype of `List<Number>` without a wildcard.
- Using `implements` instead of `extends` for an interface bound.