Логотип Workflow

Article

Generics

Topic 9. Generics

Generics in Java let you write reusable code without losing type safety. In practical terms, you define an algorithm once, and the compiler ensures that invalid types are rejected early. For beginners this is critical: generics reduce runtime failures and remove many unsafe casts.

Generics safety

1. Problem Generics Solve

Before generics, raw types were common. Code compiled, but failures appeared at runtime:

List list = new ArrayList();
list.add("Alice");
list.add(100);

String name = (String) list.get(1); // ClassCastException

With generics, invalid usage is blocked earlier:

List<String> names = new ArrayList<>();
names.add("Alice");
// names.add(100); // compile-time error
String first = names.get(0);

Core benefit: fail fast at compile time, not late in production.

2. Basic Syntax and Conventions

List<String> means “list of strings.” Map<String, Integer> means “string key, integer value.” Common type parameter names:

ParameterTypical meaning
Tgeneric type
Ecollection element
K / Vkey / value
Rresult type

Generic method example:

public static <T> void printAll(List<T> items) {
    for (T item : items) {
        System.out.println(item);
    }
}

Generic class example:

public class Box<T> {
    private T value;

    public void set(T value) { this.value = value; }
    public T get() { return value; }
}

3. extends, super, and PECS

Wildcards make APIs flexible:

public static double sum(List<? extends Number> nums) {
    double total = 0;
    for (Number n : nums) {
        total += n.doubleValue();
    }
    return total;
}

public static void addDefaults(List<? super Integer> out) {
    out.add(10);
    out.add(20);
}

Meaning:

  • ? extends Number: safe to read as Number, restricted writes.
  • ? super Integer: safe to write Integer, reads are usually Object.

PECS rule:

  1. Producer Extends for read-oriented sources.
  2. Consumer Super for write-oriented targets.

4. Why List<Integer> Is Not List<Number>

Java generics are invariant. List<Integer> is not a subtype of List<Number>:

List<Integer> ints = List.of(1, 2, 3);
// List<Number> nums = ints; // compile error

If this were allowed, Double could be inserted into an integer list.

5. Bounded Type Parameters

Sometimes a generic type must satisfy a contract:

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

Here T must be comparable to itself.

Multiple bounds are possible:

<T extends Number & Comparable<T>>

Class bound first, then interface bounds.

6. Type Erasure and Practical Impact

Java implements generics via type erasure. Checks happen at compile time, while many concrete type arguments are erased at runtime.

Consequences:

  1. You cannot do new T().
  2. You cannot reliably use instanceof List<String>.
  3. You cannot create new List<String>[10].

So generics are primarily a compile-time safety mechanism.

7. API Design with Generics

Narrow signature:

void copy(List<Object> dst, List<Object> src)

Reusable signature:

public static <T> void copy(List<? super T> dst, List<? extends T> src) {
    for (T item : src) {
        dst.add(item);
    }
}

Read-oriented helper:

public static void printNumbers(List<? extends Number> nums) {
    nums.forEach(System.out::println);
}

Write-oriented helper:

public static void fillWithZeros(List<? super Integer> target, int n) {
    for (int i = 0; i < n; i++) {
        target.add(0);
    }
}

8. Frequent Beginner Mistakes

  1. Raw types (List list) instead of parameterized types.
  2. Confusing extends with super.
  3. Forcing unchecked casts to bypass compiler feedback.
  4. Overcomplicated generic signatures where simpler API would be clearer.

9. Practical Checklist

  1. Always parameterize collection types.
  2. Use extends for read contracts.
  3. Use super for write contracts.
  4. Keep signatures readable.
  5. Add short Javadoc examples for non-trivial generic APIs.

Key Takeaway

Generics are not syntax decoration. They are a reliability tool: fewer runtime type errors, fewer manual casts, and clearer API contracts for teams.

Please login to pass quizzes.

Quiz

Check what you learned

Practice

Interactive practice

Complete tasks and check your answer instantly.