100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is a Wildcard Generic in Java?

Learn wildcard generics in Java — bounded types, PECS, and read/write safety — with examples and common interview questions.

mediumQ142 of 226 in Object Oriented Programming Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

A wildcard generic, written as "?", represents an unknown type argument in generics and lets a method accept a family of parameterized types instead of just one exact type, typically bounded with “extends” (upper bound) or “super” (lower bound).

Without wildcards, a method parameter typed "List<Number>" only accepts exactly that type, rejecting "List<Integer>" even though Integer is a Number. "List<? extends Number>" (an upper-bounded wildcard) accepts any list of Number or its subtypes and is safe to read from, but not safe to add to, since the compiler cannot guarantee the concrete element type. "List<? super Integer>" (a lower-bounded wildcard) accepts Integer or any of its supertypes and is safe to write Integer values into. This trade-off is formalized as PECS: "Producer Extends, Consumer Super." An unbounded "List<?>" is used when the element type genuinely does not matter.

  • Lets APIs accept related generic types flexibly
  • Preserves type safety without unchecked casts
  • Encodes producer vs consumer intent via PECS
  • Avoids overloading methods for every subtype combination

AI Mentor Explanation

A stadium turnstile that admits “any ticket that IS AT LEAST a member ticket or above” mirrors an upper-bounded wildcard: it accepts a family of passes without knowing the exact tier, but it will only ever let people through, never hand out new passes of an unknown tier. A collection box that accepts “any donation container that can hold a standard ticket or a broader category” mirrors the lower-bounded case: you can safely drop tickets in, but you cannot reliably read out an exact tier from it. The wildcard is the gate rule, not a fixed ticket type.

Step-by-Step Explanation

  1. Step 1

    Recognize the invariance problem

    A List<Integer> is not a List<Number> even though Integer is a Number, so exact generic types are too restrictive for many APIs.

  2. Step 2

    Apply an upper bound for reading

    Use "List<? extends T>" when the method only produces/reads values, allowing any subtype of T.

  3. Step 3

    Apply a lower bound for writing

    Use "List<? super T>" when the method only consumes/writes values of type T into the collection.

  4. Step 4

    Follow PECS

    Producer Extends, Consumer Super — pick the bound based on whether the parameter produces or consumes elements.

What Interviewer Expects

  • A correct explanation of generics invariance as the motivating problem
  • Correct distinction between "? extends T" and "? super T"
  • Mention of the PECS mnemonic (Producer Extends, Consumer Super)
  • Awareness that "? extends T" collections are effectively read-only for adding

Common Mistakes

  • Believing List<Integer> is a subtype of List<Number>
  • Adding elements to a "? extends T" typed collection and expecting it to compile
  • Confusing which bound is for producers versus consumers
  • Using unbounded "?" everywhere instead of a proper bound when one is needed

Best Answer (HR Friendly)

A wildcard generic uses a question mark to represent an unknown type so a method can accept a family of related generic types instead of one exact type. Bounding it with “extends” lets you safely read from the collection, while bounding it with “super” lets you safely write into it, and the PECS rule — Producer Extends, Consumer Super — helps me remember which to use.

Code Example

PECS: upper-bounded (producer) vs lower-bounded (consumer)
import java.util.List;

class WildcardDemo {
    // Producer: only reads from the list -> use extends
    static double sum(List<? extends Number> numbers) {
        double total = 0;
        for (Number n : numbers) {
            total += n.doubleValue();
        }
        return total;
    }

    // Consumer: only writes into the list -> use super
    static void fillWithIntegers(List<? super Integer> list, int count) {
        for (int i = 0; i < count; i++) {
            list.add(i); // safe: Integer or any of its supertypes accepted
        }
    }
}

List<Integer> ints = List.of(1, 2, 3);
WildcardDemo.sum(ints); // List<Integer> accepted by List<? extends Number>

Follow-up Questions

  • Why is List<Integer> not a subtype of List<Number>?
  • What does the PECS mnemonic stand for and when do you apply it?
  • Can you add elements to a "List<? extends Number>"? Why or why not?
  • What is the difference between an unbounded wildcard and using Object as the type?

MCQ Practice

1. What does "List<? extends Number>" guarantee?

An upper-bounded wildcard is read-safe (producer) but not write-safe, since the exact runtime type is unknown to the compiler.

2. The PECS mnemonic stands for?

PECS — Producer Extends, Consumer Super — guides which wildcard bound to use based on read vs write intent.

3. Which is true of "List<? super Integer>"?

A lower-bounded wildcard is write-safe (consumer) for Integer, but reading only guarantees an Object reference.

Flash Cards

Wildcard generic in one line?A "?" representing an unknown type argument, usable with extends/super bounds.

What does "? extends T" guarantee?Safe to read as T; unsafe to add elements (producer).

What does "? super T" guarantee?Safe to add T; reading only guarantees Object (consumer).

PECS mnemonic?Producer Extends, Consumer Super.

1 / 4

Continue Learning