Lesson 14 โ€ข Expert

    Java Generics

    Write type-safe, reusable code that catches bugs at compile time โ€” generics are what make Java's collections and APIs work seamlessly.

    ๐Ÿ“š Before You Start

    You should be comfortable with:

    • Collections (Lesson 13) โ€” ArrayList, HashMap usage
    • OOP & Inheritance (Lessons 9-10) โ€” classes and type hierarchies
    • Interfaces (Lesson 11) โ€” implementing contracts

    What You'll Learn

    • โœ… What generics are and the problem they solve
    • โœ… Generic classes: Box<T>, Pair<K, V>
    • โœ… Generic methods that work with any type
    • โœ… Bounded type parameters (<T extends Comparable>)
    • โœ… Wildcards: ?, ? extends, ? super and PECS
    • โœ… Type erasure โ€” how generics work under the hood

    1๏ธโƒฃ Why Generics? The Problem

    Real-world analogy: Generics are like a universal shipping box with a label. Without a label, anything goes in โ€” and you might accidentally break something. Once you label it "Books Only," the system prevents wrong items from going in.

    // WITHOUT generics โ€” dangerous!
    List list = new ArrayList();
    list.add("Hello");
    list.add(42);           // no error โ€” anything goes in
    String s = (String) list.get(1); // RUNTIME CRASH: ClassCastException!
    
    // WITH generics โ€” the compiler protects you
    List<String> list = new ArrayList<>();
    list.add("Hello");
    // list.add(42);        // COMPILE ERROR โ€” caught immediately!
    String s = list.get(0); // no cast needed

    Key benefit: Bugs caught at compile time are 100x cheaper than bugs found at runtime.

    2๏ธโƒฃ Generic Classes

    A generic class has type parameters that get filled in when you use it:

    public class Box<T> {
        private T content;
        public void set(T item) { content = item; }
        public T get() { return content; }
    }
    
    Box<String> nameBox = new Box<>();
    nameBox.set("Alice");
    String name = nameBox.get();  // no casting needed!
    
    // Generic Pair with TWO type parameters
    public class Pair<K, V> {
        private K key;
        private V value;
        public Pair(K key, V value) { this.key = key; this.value = value; }
    }
    
    Pair<String, Integer> entry = new Pair<>("Alice", 95);

    Convention: T = Type, E = Element, K = Key, V = Value, N = Number.

    Try It: Generic Classes

    Build type-safe Box<T> and Pair<K,V> containers

    Try it Yourself ยป
    JavaScript
    // ๐Ÿ’ก Try modifying this code and see what happens!
    // Generic Classes (Simulated)
    console.log("=== Generic Classes ===\n");
    
    // 1. Generic Box<T>
    console.log("1. Box<T> โ€” holds any single type:");
    class Box {
        #content = null;
        set(item) { this.#content = item; }
        get() { return this.#content; }
        isEmpty() { return this.#content === null; }
        toString() { return "Box[" + this.#content + "]"; }
    }
    
    let stringBox = new Box();
    stringBox.set("Hello Generics!");
    console.log("   String b
    ...

    3๏ธโƒฃ Generic Methods

    // Works with ANY array type
    public static <T> void printArray(T[] array) {
        for (T item : array) System.out.print(item + " ");
    }
    
    printArray(new String[]{"a", "b", "c"});  // a b c
    printArray(new Integer[]{1, 2, 3});       // 1 2 3
    
    public static <T> T firstNonNull(T a, T b) {
        return a != null ? a : b;
    }

    4๏ธโƒฃ Bounded Type Parameters

    <T extends X> means "T must be X or a subclass of X":

    // Only accepts Number or subclasses
    public class NumberBox<T extends Number> {
        private T value;
        public double doubleValue() { return value.doubleValue(); }
    }
    
    NumberBox<Integer> intBox = new NumberBox<>(42);   // OK
    NumberBox<Double> dblBox = new NumberBox<>(3.14);  // OK
    // NumberBox<String> strBox = ...;  // COMPILE ERROR!
    
    // Finding max in a comparable array
    public static <T extends Comparable<T>> T findMax(T[] array) {
        T max = array[0];
        for (T item : array) {
            if (item.compareTo(max) > 0) max = item;
        }
        return max;
    }

    Try It: Bounded Types & Generic Methods

    Write type-safe utility functions with bounds

    Try it Yourself ยป
    JavaScript
    // ๐Ÿ’ก Try modifying this code and see what happens!
    // Bounded Types & Generic Methods (Simulated)
    console.log("=== Bounded Types ===\n");
    
    // 1. Generic printArray โ€” works with any type
    console.log("1. Generic printArray:");
    function printArray(arr, label) {
        console.log("   " + label + ": [" + arr.join(", ") + "]");
    }
    printArray([1, 2, 3, 4, 5], "Integers");
    printArray(["Alice", "Bob", "Charlie"], "Strings");
    printArray([true, false, true], "Booleans");
    
    // 2. firstNonNull
    console.log("\n2.
    ...

    5๏ธโƒฃ Wildcards & PECS

    Wildcards let you write flexible methods that accept various generic types:

    List<?> โ€” any list (read-only usually)

    List<? extends Number> โ€” list of Number or subclass (read/produce values)

    List<? super Integer> โ€” list of Integer or parent (write/consume values)

    PECS Rule: Producer Extends, Consumer Super

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

    6๏ธโƒฃ Type Erasure โ€” Under the Hood

    Java generics are a compile-time feature only. At runtime, the JVM has no knowledge of generic types.

    Consequences:

    • โ€ข new T() is illegal โ€” JVM doesn't know what T is
    • โ€ข new T[10] is illegal โ€” can't create generic arrays
    • โ€ข instanceof T doesn't work
    • โ€ข List<String> and List<Integer> are the same class at runtime

    7๏ธโƒฃ Common Beginner Mistakes

    โŒ Mistake 1: Using raw types

    List list = new ArrayList();      // BAD โ€” raw type
    List<String> list = new ArrayList<>(); // GOOD

    โŒ Mistake 2: Thinking List<Object> accepts List<String>

    List<String> is NOT a subtype of List<Object>! Use wildcards: List<?>.

    โŒ Mistake 3: Trying to create instances of T

    Due to type erasure, new T() won't compile. Use factory methods or pass a Class<T> token.

    Try It: Build a Generic Stack

    Create a type-safe generic stack data structure

    Try it Yourself ยป
    JavaScript
    // ๐Ÿ’ก Try modifying this code and see what happens!
    // Generic Stack Data Structure (Simulated)
    console.log("=== Generic Stack<T> ===\n");
    
    class Stack {
        constructor() { this.items = []; }
        push(item) { this.items.push(item); }
        pop() {
            if (this.isEmpty()) throw new Error("Stack underflow!");
            return this.items.pop();
        }
        peek() {
            if (this.isEmpty()) throw new Error("Stack is empty!");
            return this.items[this.items.length - 1];
        }
        size() { ret
    ...

    ๐Ÿ“‹ Quick Reference

    SyntaxExampleMeaning
    <T>class Box<T>Type parameter
    <T extends X><T extends Number>Upper bound
    <?>List<?>Unknown type (read-only)
    <? extends T>List<? extends Number>Producer โ€” read values
    <? super T>List<? super Integer>Consumer โ€” write values
    <K, V>Pair<String, Integer>Multiple type params

    ๐ŸŽ‰ Lesson Complete!

    You now understand generics โ€” type parameters, bounded types, wildcards, and PECS. This knowledge is essential for writing professional, type-safe Java code.

    Next up: Advanced Methods โ€” master overloading, varargs, method references, and recursion.

    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