-
Notifications
You must be signed in to change notification settings - Fork 0
Generics
Thomas Czogalik edited this page Sep 3, 2018
·
2 revisions
Summary of the book "Java generics and collections" by Maurice Naftalin [1]
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; ...
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
- 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
- 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 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
- 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);
[1] Java Generics and Collections, link: http://shop.oreilly.com/product/9780596527754.do