Summary on some java generics presentations/postings

Gilad Bracha, Generics in the Java Programming Language

1. Wildcard is a supertype of all kinds of collections.

void print Collection(Collection<?> c) {
  for (Object e: c) // Wildcard is an object

2. You can not add anything into the container of ?.

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Impossible, because ? is unknown type. Null is an exception.

3. Use ? extends SuperClass for reading

public void drawAll(List<? extends Shape> shapes) { ... }

4. To add something to generic collection, use generic methods

static <T> void fromArrayToCollection(T[ ] a, Collection<T> c) {
  for(T o: a) c.add(o);

Why? Because the following does not work:

static void fromArrayToCollection(Object[ ] a, Collection<?> c) {
  for (Object o: a) c.add(o); // No, you can't add something to the collection of ?.

6. Generic Methods vs Wildcard
Generic methods allow type parameters to be used to express dependencies among the types of one or more arguments to a method and/or its return type. If there isn’t such a dependency, use wildcard. Consider:

interface Collection<E> { 
  // reading from c. So, it's okay to use ?.
  public boolean containsAll(Collection<?> c);

  // also for reading.
  public boolean addAll(Collection<? extends E> c);

interface Collection<E> { 
  public <T> boolean containsAll(Collection<T> c);
  public <T extends E> boolean addAll(Collection<T> c);

Using wildcard is short and efficient. Moreover, wildcards can be used by local variables/fields/etc, e.g., List<?> aList = …;

7. Generic classes are shared.

List<String> l1 = new ArrayList();
List<Integer> l2 = new ArrayList();
System.out.println(l1.getClass() == l2.getClass()); // prints true

8. Type variables do not exist at run time

// Unchecked warning
Collections<String> cstr = (Collection<String>) new ArrayList<String>();

// Unchecked warning
<T> T badCast(T t, Object o) { return (T) o; }

9. Class Literals as Run-time Type Tokens

Collection<EmpInfo< emps =, ...);
public static Collection select(Class<T> c, String sqlStatement) {
  T item = c.newInstance();

10. More fun with Wildcards

// Let me write T into Sink which accepts parents of T.
public static <T> T writeAll(Collection<T> coll, Sink<? super T> snk) { ... }

// Comparable
TreeSet(Comparator<? super E> c)

// max
public static <T extends Comparable<? super T>>
T max(Collection<T> coll)

Joshua Bloch, Effective Java Reloaded, JavaOne, 2006

1. Prefer Wildcards To Type Parameters
The rule: If a type variable appears only once in a method signature, use wildcard instead
The exception: conjunctive type

<E, T extends Serializable & List<E>> void f(T list) { ... }

2. Bounded wildard to the Rescue
Use extends when parameterized instance is producer(“for read”)
Use super when parameterized instance is consumer(“for write”)

public interface Shop<T> {
  T buy();
  void sell(Collection<? extends T> lot);
  void buy(int numItems, Collection<? super T> myStuff);

3. Avoid Bounded Wildcards in Return Types
They force client to deal with wildcards directly. Rarely, you do need it.

4. Typesafe Heterogeneous Container(THC) Example

public class Favorites {

  private Map<Class<?>, Object> favorites =
      new HashMap<Class<?>, Object> (); // Heterogeneous Map

  public <T> void setFavorite(Class<T> klass, T thing) {
    favorites.put(klass, thing);

  public <T> T getFavorite(Class<T> klass) {
    return klass.cast(favorites.get(klass));

  public static void main(String[] args) {
    Favorites f = new Favorites();
    f.setFavorite(String.class, "Java");
    f.setFavorite(Integer.class, 0xcafebabe);
    String s = f.getFavorite(String.class);
    int i = f.getFavorite(Integer.class);

Neal Gafter, Super Type Token

1. Type Token
Type token refers to a way to refer to the Class instance of a specific class. For example, Class<String>. This enables THC(Typesafe Heterogeneous Container). But the problem is that referring to the class of a generic class, say, List<String>.class is not possible.

2. Super Type Token
THC does not support f.setFavorite(List<String>.class, collections.emptyList()), because of Erasure. How can we do that?

Basic idea is as follows:

public abstract class TypeReference<T> {}
TypeReference<List<String>> x = new TypeReference<List<String>>() {}; // Now I have type information stored somewhere

Concrete implementation of this idea:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

 * References a generic type.
 * @author (Bob Lee)
public abstract class TypeReference<T> {

    private final Type type;
    private volatile Constructor<?> constructor;

    protected TypeReference() {
        Type superclass = getClass().getGenericSuperclass();
        if (superclass instanceof Class) {
            throw new RuntimeException("Missing type parameter.");
        this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];

     * Instantiates a new instance of {@code T} using the default, no-arg
     * constructor.
    public T newInstance()
            throws NoSuchMethodException, IllegalAccessException,
                   InvocationTargetException, InstantiationException {
        if (constructor == null) {
            Class<?> rawType = type instanceof Class<?>
                ? (Class<?>) type
                : (Class<?>) ((ParameterizedType) type).getRawType();
            constructor = rawType.getConstructor();
        return (T) constructor.newInstance();

     * Gets the referenced type.
    public Type getType() {
        return this.type;

    public static void main(String[] args) throws Exception {
        List<String> l1 = new TypeReference<ArrayList<String>>() {}.newInstance();
        List l2 = new TypeReference<ArrayList>() {}.newInstance();

Similar Posts:

Comments 3