Pragmatic Programmer Issues

Java Generics and Collections

Comments: 2

I read this book twice, and I suggest every java developer two read it twice or more. Some time ago I passed SCJP before this exam I thought that I know Generics but I didn’t. So when I saw this book in Roche Library I knew I should read it.

The book has two parts, one of them is about Generics (was read by me more than twice), second part is about java collections.

First at all we must know that generics are implemented by erasure. So once code is compiled there is no more information about Generics. Second important thing to remember is that List<Integer> has no relation with List<Number>. This one helps us to understand everything else. So once again List<Integer> is not subclass of List<Number> nor List<Number> is subclass of List<Integer>. This types are different, repeat with me D I F F E R E N T.

Once again:

  • Erasure
  • No parent-child relation

Ok so you ask what if I want a List with Integer and Float types. The answer is magical “? extends E” called wildcard, which means that it is legal to have type E and any type that is a subtype of E. For exampe Collection class have method

public boolean addAll(Collection<? extends E> collection);

which allows add all class and sublcass of type E. The second magic literal is “? super T” which simply means that it represents any type that is supertype of T.

This construction compared to arrays behavior makes three different subtyping.

Phrase Subtype type condition
T[] covariant if T is subtype of S
List<T> invariant if T is identical as S
List<? extends T> covariant if T is subtype of S
List<? super T> contravariant if T is supertype of S

We can’t use wildcards in :

  • instance creation : List<? extends Integer> list = new List<? extends Integer>();
  • supertype declaration: MyClass extends List<? extends Integer>
  • generic method call: Collections.<? extends Integer>emptyList();

Important note is that List<? extends Integer> is a wildcard but List<List<? extends Integer>> is NOT.

One thing to mention is that parametrized type is reificated, so in runtime List<Number> and List<String> is simple raw List. Hence we can’t use instanceof with parametrized type. The only one generic type is <?> wildcard.

There are more advanced topics related to generics including tips how to migrate from no generic code to generic one.

Second part of the book is about java collections. There are full characterization of class hierarchy and the most important thing is that all implementation has comparison of performance. So everyone can choose suitable implementation for task.

Principles to remember:

Cast-iron guarantee: the implicit casts added by the compilation of generics never fail.

The Get and Put Principle: use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into structure, and don’t use a wildcard when you do both get and put.

The Principle of Truth in Advertising: the reified type of an array must be a subtype of the erasure of its static type.

In my opinion all java programmers should have this book on his shelf and I assure you I will get my own.

Read more on Java Generics, there is a generic tutorial.




The main problem in generics are wildcards. And IMHO the reason is in broken subclassing mechanism.


I find many generic problems too complex, to be valuable to be used in typical project.

Maybe some day I will have so many patience to go deeply into generics mystery.

I think this is the most unknown piece of java for a typical Java developer