All topics
library
intermediate

Generics Fundamentals

Understand type parameters, type safety at compile time, and why generics exist.

Generics let you parameterise a type, so the compiler can check what goes in and out.

Generics = labeled containers. A box labeled 'Books Only' (Box<Book>) prevents you from putting shoes in at compile time — no need to check every item when you take it out.

Key Concepts

1
    List<String> names = new ArrayList<>();
    names.add("Asha");
    String s = names.get(0);        // no cast
2
Before generics, every retrieval was a cast:
    List names = new ArrayList();
    names.add("Asha");
    names.add(42);                  // nothing stopped this
    String s = (String) names.get(1);    // ClassCastException, at runtime
3
The error moved from runtime to compile time. That is the entire point.
4
A generic class.
    class Box<T> {
      private T value;
      void set(T v) { value = v; }
      T get() { return value; }
    }
5
    Box<String> b = new Box<>();     // the diamond infers String
6
A generic method declares its parameter before the return type:
7
    static <T> T firstOrNull(List<T> list) {
      return list.isEmpty() ? null : list.get(0);
    }
8
The type is inferred from the argument, so you call it as firstOrNull(names).
firstOrNull(names)
9
A generic interface.
    interface Comparable<T> { int compareTo(T o); }
    class Age implements Comparable<Age> { ... }
10
The naming convention.
    T  type       E  element      K  key
    V  value      N  number       R  result
11
What you cannot do, all because of type erasure:
12
    new T()                  no -- the type is unknown at runtime
    new T[10]                no
    obj instanceof T         no
    static T field           no -- statics are shared across all T
    List<int>                no -- primitives are not types here
13
And generics are invariant.
    List<String> strings = new ArrayList<>();
    List<Object> objects = strings;        // will not compile
14
Which looks wrong, since a String is an Object. But if it compiled you could add an Integer through objects and then read it as a String. Wildcards exist to recover the flexibility safely.
StringObjectIntegerobjects
15
What the interviewer is probing.1. "Why is List<String> not a List<Object>?" Probing: invariance. Stalls: "It should be, String is an Object." Moves up: if it were, you could add an Integer through the Object reference and read it back as a String — wildcards exist to recover the flexibility safely.
16
2. "What problem did generics actually solve?" Probing: whether you can state the before and after. Stalls: "Type safety." Moves up: they moved ClassCastException from runtime to compile time, and removed the cast on every retrieval.
17
3. "Can you write new T()?" Probing: erasure. Stalls: "Yes, inside a generic class." *Moves up:* no — T is erased, so the runtime does not know what to construct; pass a Class<T> or a supplier instead.
18
4. "Why can a generic class not have a static field of type T?" Probing: what statics are shared across. Stalls: "No reason." Moves up: statics are shared by every parameterisation, so there is no single T for them to be — Box<String> and Box<Integer> share the field.