Courses/Java/Advanced Generics

    Lesson 20 โ€ข Advanced

    Advanced Generics: Wildcards & Type Erasure

    Upper/lower bounds, ? wildcards, and how type erasure affects runtime behavior.

    ๐Ÿ“š Before You Start

    You should understand:

    • Generics (Lesson 14) โ€” Box<T>, type parameters, bounds
    • Collections (Lesson 13) โ€” ArrayList, HashMap usage
    • Inheritance (Lesson 10) โ€” class hierarchies and polymorphism

    What You'll Learn

    • โœ… Upper bounded wildcards: ? extends T
    • โœ… Lower bounded wildcards: ? super T
    • โœ… Unbounded wildcards: ?
    • โœ… PECS principle (Producer Extends, Consumer Super)
    • โœ… Type erasure and its implications
    • โœ… Generic method type inference

    1๏ธโƒฃ Understanding Wildcards

    ๐Ÿ’ก Analogy: Delivery Boxes โ€” ? extends Fruit is a "read-only fruit box" โ€” you can take items out (they're at least Fruit), but can't put items in (is it an Apple box? Orange box?). ? super Apple is a "write-only apple-compatible box" โ€” you can put Apples in, but when reading you only know it's Object.

    PECS: The Golden Rule โ€” Producer Extends, Consumer Super. Reading from a collection โ†’ use extends. Writing to a collection โ†’ use super.

    // PRODUCER โ€” reads from the list
    public double sum(List<? extends Number> numbers) {
        double total = 0;
        for (Number n : numbers) total += n.doubleValue();
        return total;
    }
    // Works with List<Integer>, List<Double>, List<Number>
    
    // CONSUMER โ€” writes to the list
    public void addIntegers(List<? super Integer> list) {
        list.add(1); list.add(2);
    }
    // Works with List<Integer>, List<Number>, List<Object>

    Try It: Wildcards & PECS in Action

    See how upper and lower bounded wildcards control read/write access

    Try it Yourself ยป
    JavaScript
    // ๐Ÿ’ก Try modifying this code and see what happens!
    // Wildcards & PECS (Simulated)
    console.log("=== Wildcards ===\n");
    
    // 1. Upper bounded (? extends Number) โ€” READ only
    console.log("1. UPPER BOUNDED (? extends Number):");
    console.log("   Can READ but not WRITE\n");
    
    function sumOfList(numbers) {
        return numbers.reduce((sum, n) => sum + n, 0);
    }
    
    let integers = [1, 2, 3, 4, 5];
    let doubles = [1.5, 2.5, 3.5];
    console.log("  Sum of integers:", sumOfList(integers));
    console.log("  Sum of doubl
    ...

    2๏ธโƒฃ Type Erasure: Why It Matters

    At compile time, Java checks generics rigorously. But at runtime, all generic type information is erased โ€” List<String> becomes just List.

    Consequences:

    • โŒ new T() โ€” can't create generic instances
    • โŒ instanceof List<String> โ€” can't check generic types
    • โŒ new T[10] โ€” can't create generic arrays
    • โœ… Class<T> token โ€” pass type info explicitly

    3๏ธโƒฃ Generic Method Type Inference

    Java can often infer type parameters automatically. The diamond operator <> (Java 7+) lets the compiler figure out the types:

    // Compiler infers T = String
    List<String> list = new ArrayList<>();
    
    // Generic method โ€” compiler infers types from arguments
    public static <T extends Comparable<T>> T max(T a, T b) {
        return a.compareTo(b) > 0 ? a : b;
    }
    
    // Infers T = Integer
    int m = max(3, 7); // 7

    Try It: Type Inference & Bounded Methods

    Write generic utility functions with type inference and bounds

    Try it Yourself ยป
    JavaScript
    // ๐Ÿ’ก Try modifying this code and see what happens!
    // Type Inference & Bounded Methods (Simulated)
    console.log("=== Generic Method Inference ===\n");
    
    // 1. findMax with comparator
    function findMax(arr, comparator) {
        if (arr.length === 0) return null;
        let max = arr[0];
        for (let item of arr) {
            if (comparator(item, max) > 0) max = item;
        }
        return max;
    }
    
    console.log("1. findMax with different types:");
    console.log("  Max number:", findMax([3, 1, 4, 1, 5, 9], (a, b) => a
    ...

    4๏ธโƒฃ Advanced Wildcard Patterns

    Collections.copy(): The best real-world PECS example โ€” source is ? extends T (producer) and dest is ? super T (consumer):

    // Java Collections.copy signature:
    public static <T> void copy(
        List<? super T> dest,    // CONSUMER โ€” writes
        List<? extends T> src    // PRODUCER โ€” reads
    )

    Try It: Build Generic Utility Functions

    Create a type-safe utility library with generic methods

    Try it Yourself ยป
    JavaScript
    // ๐Ÿ’ก Try modifying this code and see what happens!
    // Generic Utility Library (Simulated)
    console.log("=== Generic Utilities ===\n");
    
    // 1. Generic zip (combine two arrays into pairs)
    function zip(a, b) {
        let result = [];
        let len = Math.min(a.length, b.length);
        for (let i = 0; i < len; i++) result.push([a[i], b[i]]);
        return result;
    }
    
    console.log("1. Zip:");
    let names = ["Alice", "Bob", "Charlie"];
    let scores = [95, 87, 92];
    zip(names, scores).forEach(([name, score]) => {
        c
    ...

    5๏ธโƒฃ Common Mistakes

    โŒ
    Using raw types: List list = new ArrayList(); bypasses all safety. Always parameterize.
    โŒ
    Assuming List<Dog> is List<Animal>: Generics are invariant. Use List<? extends Animal> for covariance.
    โŒ
    Creating generic arrays: new T[10] doesn't compile. Use List<T> instead.

    6๏ธโƒฃ Pro Tips

    ๐Ÿ’ก When in doubt, use PECS. Reading โ†’ ? extends. Writing โ†’ ? super. Both โ†’ concrete type.

    ๐Ÿ’ก Diamond operator <> (Java 7+) lets the compiler infer: List<String> list = new ArrayList<>();

    ๐Ÿ’ก Study Collections.copy() โ€” it's the canonical PECS example in the JDK.

    ๐Ÿ“‹ Quick Reference

    WildcardMeaningRead/Write
    ? extends TT or its subtypesRead โœ… Write โŒ
    ? super TT or its supertypesRead โŒ Write โœ…
    ?Any typeRead as Object only
    T extends ComparableT must be ComparableFull access

    ๐ŸŽ‰ Lesson Complete!

    You now understand advanced generics including wildcards, PECS, and type erasure!

    Next: Streams API โ€” build complex data pipelines with filter, map, collect, and flatMap.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy Policy โ€ข Terms of Service