🎓 A1Learner
🔍
0 of 40 lessons completed

Java Generic Classes

A generic class is a class written with a type parameter, a placeholder name inside angle brackets. One class then works for many types while the compiler checks every value.

A box for text

Box is declared with the placeholder T. Filling it with String makes set accept text and get answer text.

public class Main {
  public static void main(String[] args) {
    Box<String> box = new Box<>();
    box.set("Ana");
    System.out.println(box.get());
    System.out.println(box.get().length());
  }
}

class Box<T> {
  private T value;

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

  T get() {
    return value;
  }
}

A box for numbers

The same Box class now holds an Integer. The value comes back ready for arithmetic, with no cast.

public class Main {
  public static void main(String[] args) {
    Box<Integer> box = new Box<>();
    box.set(40);
    System.out.println(box.get() + 2);
  }
}

class Box<T> {
  private T value;

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

  T get() {
    return value;
  }
}

Two type parameters

Pair declares K and V in one header. One pair joins a name with a score.

public class Main {
  public static void main(String[] args) {
    Pair<String, Integer> pair = new Pair<>("Ana", 92);
    System.out.println(pair.getKey());
    System.out.println(pair.getValue());
  }
}

class Pair<K, V> {
  private K key;
  private V value;

  Pair(K key, V value) {
    this.key = key;
    this.value = value;
  }

  K getKey() {
    return key;
  }

  V getValue() {
    return value;
  }
}

Example

public class Main {
  public static void main(String[] args) {
    Pair<String, Integer> first = new Pair<>("Ana", 92);
    Pair<String, Integer> second = new Pair<>("Ben", 88);
    Box<Pair<String, Integer>> box = new Box<>();
    box.set(first);
    System.out.println(box.get().getKey() + " scored " + box.get().getValue());
    System.out.println(second.getKey() + " scored " + second.getValue());
  }
}

class Box<T> {
  private T value;

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

  T get() {
    return value;
  }
}

class Pair<K, V> {
  private K key;
  private V value;

  Pair(K key, V value) {
    this.key = key;
    this.value = value;
  }

  K getKey() {
    return key;
  }

  V getValue() {
    return value;
  }
}

Key points

  • The type parameter T is a placeholder that the caller fills with a real type.
  • Box<String> holds text and Box<Integer> holds whole numbers, with no casts anywhere.
  • The compiler rejects a value of the wrong type for a filled box at compile time.
  • A class can declare two type parameters, like K for a key and V for a value in Pair.
  • The same class code serves every type argument, so one Pair class holds any key and value pairing.

In this example, a Box holds a whole Pair because a type argument can itself be a filled generic type. The prints read the key and value back out of each pair.

Note

Type parameters are written with single capital letters by convention, like T, K and V.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does the compiler do when code stores an Integer in a Box<String>?