Chapter 8 3 min read
Save

Generics

Object Oriented Programming in Java · BCA · Updated Apr 15, 2026

Table of Contents

Introduction

Generics, introduced in Java 5, let you parameterize classes, interfaces, and methods with types. Before generics, collections held Object references and required explicit casts. Generics give you compile-time type safety and eliminate casts, making code safer and more readable.

Without vs With Generics

// Pre-generics
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0); // cast required

// With generics
List<String> list2 = new ArrayList<>();
list2.add("hello");
String s2 = list2.get(0); // no cast

Generic Class

public class Box<T> {
    private T value;
    public void set(T v) { value = v; }
    public T get() { return value; }
}
Box<Integer> b1 = new Box<>();
b1.set(42);
Box<String> b2 = new Box<>();
b2.set("Hello");

The T is a type parameter. Convention names: T (type), E (element), K (key), V (value), N (number).

General Form of a Generic Class

public class Pair<K, V> {
    private K key;
    private V value;
    public Pair(K k, V v) { key = k; value = v; }
    public K getKey() { return key; }
    public V getValue() { return value; }
}

Generic Methods

public static <T> T firstOf(List<T> list) {
    return list.isEmpty() ? null : list.get(0);
}
String s = firstOf(Arrays.asList("a","b"));
Integer i = firstOf(Arrays.asList(1,2,3));

The type parameter <T> appears before the return type. The compiler infers T from the argument.

Bounded Type Parameters

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

<T extends Number> means T must be Number or a subclass. You can compose bounds: <T extends Number & Comparable<T>>.

Wildcards

  • List<?> — list of unknown type (read-only)
  • List<? extends Number>upper bound; any Number subtype (producer)
  • List<? super Integer>lower bound; Integer or any supertype (consumer)

The PECS rule: Producer Extends, Consumer Super.

Generic Interfaces

public interface Container<T> {
    void add(T item);
    T get(int i);
}
public class StringList implements Container<String> {
    private List<String> items = new ArrayList<>();
    public void add(String s) { items.add(s); }
    public String get(int i) { return items.get(i); }
}

Generic Constructors

A generic class constructor can itself have its own type parameter independent of the class:

class Holder<T> {
    private T value;
    public <U extends T> Holder(U u) { value = u; }
}

Type Erasure

Java implements generics using type erasure: the compiler verifies types at compile time, then removes parameter types at runtime. After compilation, List<String> and List<Integer> are both just List. Consequences: you cannot write new T(), T.class, or instanceof T.

Polymorphism in Generics

List<Integer> is not a subtype of List<Number> even though Integer is a subtype of Number. Use wildcards (List<? extends Number>) to achieve polymorphic behaviour safely.

Summary

Generics provide compile-time type safety and eliminate casts. Parameterize classes and methods with type variables, apply bounded types for constraints, and use wildcards for flexibility. Remember type erasure — generics live only at compile time.

Important Questions

  1. What are generics? Why were they added to Java 5?
  2. Write a generic class Pair<K,V>.
  3. What are bounded type parameters? Give an example.
  4. Explain wildcards: ?, ? extends, ? super.
  5. State and explain the PECS rule.
  6. Write a generic method that returns the maximum of a list.
  7. What is type erasure? List its consequences.
  8. Why is List<Integer> not a subtype of List<Number>?

Related Notes

Discussion

0 comments

Join the discussion

Log in to share your thoughts and help fellow students.

Log in to comment

No comments yet. Be the first to share your thoughts!