Skip to content

Generics

Thomas Czogalik edited this page Sep 3, 2018 · 2 revisions

Summary of the book "Java generics and collections" by Maurice Naftalin [1]

Generics

Generics (Java) vs. Templates (C++)

Generics are defined by erasure meaning the following examples have the same byte code:

List<String> w = new ArrayList<>();
String s = w.get(0);

List w = new ArrayList();
String s = (String) w.get(0);

Templates are defined by expansion meaning each of the following creates a new copy of the code:

List<Integer> u; ...
List<Number> v; ...
List<String> w; ...

Wildcards

List<? extends T>

  • ? is subtype of T
  • Get elements out of List, but cannot put elements into List, because another element of subtyp of T can already be in List

List<? super T>

  • ? is supertype of T
  • Put elements into List, but cannot get elements ou of List

Get/Put Principle

  • use extends if you always get elements out of a list
  • use super if you always put elements into a list
  • use neither of them if you do both

Bounded Type Variable

  • always indicated by the keyword extends
// means T is bound by Comparable<T> and T must implement that interface
public static <T extends Comparable<T>> T max(Collection<T> coll) {
    T candidate = coll.iterator().next();
    for (T elt : coll) {
        if (candidate.compareTo(elt) < 0) candidate = elt;
    }
    return candidate;
}

Static Members

  • static members of a generic class are shared across all instantiations of that class, including instantiations at different types
  • Static members of a class cannot refer to the type parameter of a generic class
  • when accessing a static member the class name should not be parameterized
class Cell<T> {
  private final int id;
  private final T value;
  private static int count = 0;
  private static synchronized int nextId() { return count++; }
  public Cell(T value) { this.value=value; id=nextId(); }
  public T getValue() { return value; }
    public static List<T> getValues() { return values; } // illegal
  public int getId() { return id; }
  public static synchronized int getCount() { return count; }
}
...
Cell<String> a = new Cell<String>("one");
Cell<Integer> b = new Cell<Integer>(2);
assert a.getId() == 0 && b.getId() == 1 && Cell.getCount() == 2;

//!!!when accessing a static member the class name should not be parameterized!!!
Cell<Integer>.getCount(); // compile-time error
Cell<?>.getCount();       // compile-time error

Design Pattern

Visitor

Strategy

Observer

Collections

CheckedList

  • ensure the collection doesn't get anything in it of the wrong type
  • used if old code is used where Generics did not exist
Collections.checkedList(
      new ArrayList<String>(uncertainList.size()), String.class
      ).addAll(uncertainList);

References

[1] Java Generics and Collections, link: http://shop.oreilly.com/product/9780596527754.do

Clone this wiki locally