Lesson 13 of 20

Generics

Generics

Generics let you write type-safe classes and methods that work with any type:

class Pair<A, B> {
    A first;
    B second;

    Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ")";
    }
}

Pair<String, Integer> p = new Pair<>("hello", 42);
System.out.println(p);         // (hello, 42)
System.out.println(p.first);   // hello

Generic Methods

static <T extends Comparable<T>> T min(T a, T b) {
    return a.compareTo(b) <= 0 ? a : b;
}

System.out.println(min(3, 7));          // 3
System.out.println(min("apple", "banana"));  // apple

Type Bounds

  • <T extends Comparable<T>> — T must implement Comparable
  • <T extends Number> — T must be a Number subtype

Type Erasure

Java generics are a compile-time feature only. The compiler checks type safety and then erases all generic type information, replacing type parameters with Object (or the bound type). This means Stack<Integer> and Stack<String> are the same class at runtime — you cannot use instanceof with generic types or create arrays of a generic type directly. This is why the Stack implementation below uses Object[] internally and casts on pop().

Your Task

Implement:

  • Generic class Stack<T> with push(T), T pop(), int size()
  • Generic method <T extends Comparable<T>> T min(T a, T b)

Push 10, 20, 30 onto the stack; print size, pop twice, print size again. Then print min(3, 7) and min("apple", "banana").

TeaVM (WASM) loading...
Loading...
Click "Run" to execute your code.