"Bueno, finalmente, otra pequeña lección sobre genéricos".

"Ahora te voy a decir cómo sortear el borrado de tipos".

"Ah. Eso es algo que quiero saber."

"Como probablemente ya sepa, Java tiene un tipo Class, que se usa para almacenar una referencia a la clase de un objeto. "Aquí hay algunos ejemplos:"

Ejemplos
Class clazz = Integer.class;
Class clazz = String.class;
Class clazz = "abc".getClass();

"Ah".

"Pero lo que probablemente no sepa es que también hay una clase genérica llamada Clase. Y las variables de Clase genérica solo pueden almacenar referencias al tipo determinado por el argumento de tipo.  Aquí hay algunos ejemplos:"

Ejemplos
Class<Integer> clazz1 = Integer.class; // Everything works well
Class<String> clazz2 = Integer.class; // Compilation error
Class<String> clazz1 = String.class; // Everything works well
Class<String> clazz2 = int.class; // Compilation error
Class<? extends String> clazz1 = "abc".getClass(); // Everything works well
Class<Object> clazz2 = "abc".getClass(); // Compilation error

"¿Por qué funciona así?"

"Bueno, el valor del campo de clase para Integer (es decir, Integer.class) es en realidad un objeto Class<Integer>".

"Pero sigamos".

"Aprovechando el hecho de que Class<T> es genérica y que este tipo de variable solo puede contener un valor de tipo T, puede juntarlas de una manera ingeniosa como esta:"

Ejemplo
class Zoo<T>
{
 Class<T> clazz;
 ArrayList<T> animals = new ArrayList<T>

 Zoo(Class<T> clazz)
 {
  this.clazz = clazz;
 }

 public T createNewAnimal()
 {
  T animal = clazz.newInstance();
  animals.add(animal);
  return animal
 }
}
Uso
Zoo<Tiger> zoo = new Zoo<Tiger>(Tiger.class); // This is where we pass the type!
Tiger tiger = zoo.createNewAnimal();

"Esta no es una maniobra súper complicada: simplemente estamos pasando una referencia al tipo deseado. Pero, si simplemente usamos Class en lugar de Class<T>, entonces alguien podría pasar accidentalmente dos tipos diferentes: uno como el argumento T , y otro al constructor".

"Ah. Entiendo. No ha pasado nada sobrenatural, pero tampoco nada terrible. Hay una referencia al tipo, y puedes usarlo. Funciona y eso es lo suficientemente bueno para mí".

"¡El niño se convierte en hombre! 'Funciona y eso es lo suficientemente bueno para mí' suele ser la mejor opción".

"Se podrían rehacer muchas cosas en Java ahora, pero necesitamos mantener la compatibilidad con el código antiguo".

"Las decenas de miles de bibliotecas pulidas populares son el argumento más poderoso para Java en la actualidad. Por lo tanto, Java sigue siendo el lenguaje más popular al mantener la compatibilidad con versiones anteriores, por lo que no puede introducir innovaciones radicales".

"Bueno, voy a construir mi propio Java con blackjack y..."

"Bien, ya estoy cansado por el día. Hasta la próxima".

"Adiós, Rishi, y gracias por una lección tan interesante".