"Well, finally — another small lesson on generics."
"Now I'm going to tell you how to get around type erasure."
"Ah. That's something I want to know."
"As you probably already know, Java has a Class type, which is used to store a reference to an object's class. "Here are some examples:"
Class clazz = Integer.class;
Class clazz = String.class;
Class clazz = "abc".getClass();
"Ah."
"But what you probably don't know is that there is also a generic class called Class. And generic Class variables can only store references to the type determined by the type argument. Here are some examples:"
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
"Why does it work like that?"
"Well, the value of the class field for Integer (i.e. Integer.class) is actually a Class<Integer> object."
"But let's keep going."
"Taking advantage of the fact that Class<T> — is a generic and that this type of variable can only hold a value of type T, you can put them together in a slick way like this:"
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
}
}
Zoo<Tiger> zoo = new Zoo<Tiger>(Tiger.class); // This is where we pass the type!
Tiger tiger = zoo.createNewAnimal();
"This isn't a super tricky manoeuvre — we're simply passing a reference to the desired type. But, if we simply used Class instead of Class<T>, then someone might accidentally pass two different types: one as the T argument, and another to the constructor."
"Ah. I understand. Nothing supernatural has happened, but nothing terrible either. There is a reference to the type, and you can use it. It works and that's good enough for me."
"The boy becomes a man! 'It works and that's good enough for me' is often the best option."
"A lot of things could be redone in Java now, but we need to maintain compatibility with old code."
"The tens of thousands of popular polished libraries are the most powerful argument for Java today. Thus, Java remains the most popular language by maintaining backward compatibility, so it cannot introduce radical innovations."
"Well, I'm going to build my own Java with blackjack and…"
"Fine, I'm already tired from the day. Until next time."
"Goodbye, Rishi, and thanks for such an interesting lesson."
GO TO FULL VERSION