Os generics em Java não foram feitos para tornar seu programa mais rápido ou mais eficiente: eles foram feitos para resolver um outro problema, que é o uso de ‘casts’ excessivo e indevido que pode ocorrer sem generics. Você poderia chamar o recurso de ‘autocasting’.
Por exemplo, para ter um ArrayList de String, você escreveria:
List l = new ArrayList(); // aqui não há nada que indique que a sua intenção
// é construir uma lista que só contém strings.
l.add ("str1");
l.add ("str2");
String s = (String) l.get(0); // aqui você está chutando que há uma String
// na primeira posição da lista.
// Se não houver, você vai ter um ClassCastException.
Agora, como você deve saber melhor que eu, você só precisa escrever:
List< String > l = new ArrayList < String > (); // aqui você diz
// claramente que quer construir uma lista que só contém strings.
l.add ("str1");
l.add ("str2");
String s = l.get(0); // Você sabe que há uma String na primeira posição da lista.
Só que devido ao fenômeno de ‘erasure’, o código “generics” escrito acima é exatamente igual, em termos de runtime, ao código anterior, incluindo o cast para String que não aparece mais explicitamente no código com ‘generics’.
Parece um pouco de perfumaria, mas você irá ver na prática que o recurso de Generics torna seu código mais claro em alguns pontos (é claro que você normalmente não vai precisar de declarar uma rotina tal como java.util.Collections.max(), cuja declaração é public static < T extends Object & Comparable< ? super T > > T max (Collection < ? extends T > coll) )