Generics in Java

Site Admin · 11 Sep 2026 · 11 views

Code That Works for Many Types

Generics let you write a class or method once and use it with different types safely. The famous example is collections: List<String> is a list of Strings, List<Integer> is a list of Integers - both from the same ArrayList class.

Why They Exist - the Old Problem

// Without generics (old code)
List raw = new ArrayList();
raw.add("hello");
raw.add(123);        // mixed types allowed - dangerous
Object o = raw.get(0);  // everything comes back as Object

// With generics: the compiler checks every add and get
List<String> words = new ArrayList<>();
words.add("hello");
words.add(123);        // compile error - caught early!
String first = words.get(0); // no cast needed

Generic Classes

class Box<T> {
    private T item;

    void put(T item) { this.item = item; }
    T get() { return item; }
}

Box<Integer> intBox = new Box<>();
intBox.put(42);
System.out.println(intBox.get()); // 42

Generic Methods

static <T> T firstElement(List<T> list) {
    return list.get(0);
}
String s = firstElement(List.of("a", "b"));
Integer n = firstElement(List.of(1, 2));

Wildcards

A wildcard ? allows the method to accept collections of any element type.

static void printAll(List<?> items) {
    for (Object item : items) System.out.println(item);
}
printAll(List.of(1, 2, 3));
printAll(List.of("x", "y"));

Bounded wildcards constrain the type: List<? extends Number> accepts lists of Integer, Double, Number and so on.

Bounded Type Parameters

static <T extends Number> double sum(List<T> numbers) {
    double total = 0.0;
    for (T n : numbers) total += n.doubleValue();
    return total;
}

Generics overview

Collections without generics

Key Points

  • Generics shift type errors from runtime to compile time.
  • Type parameters go in angle brackets and replace Object casts.
  • Wildcards (?) and bounds (extends) make APIs flexible.
Share this post:

Comments (0)

Please login or register to comment.