“好吧,最後——關於仿製藥的又一堂小課。”

“現在我要告訴你如何繞過類型擦除。”

“啊。這就是我想知道的事情。”

“您可能已經知道,Java 有一個 Class 類型,用於存儲對對像類的引用。”以下是一些示例:

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

“啊。”

“但你可能不知道的是,還有一個泛型類,叫做 Class。而泛型類變量只能存儲對由類型參數確定的類型的引用。 下面是一些例子:”

例子
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

“為什麼會這樣?”

“嗯,Integer 的類字段的值(即 Integer.class)實際上是一個 Class<Integer> 對象。”

“但讓我們繼續前進吧。”

“利用 Class<T> — 是泛型這一事實,並且這種類型的變量只能保存 T 類型的值,您可以像這樣巧妙地將它們組合在一起:”

例子
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();

“這不是一個非常棘手的操作——我們只是傳遞對所需類型的引用。但是,如果我們只是使用 Class 而不是 Class<T>,那麼有人可能會不小心傳遞兩種不同的類型:一種作為 T 參數,另一個給構造函數。”

“啊。我明白了。沒有發生任何超自然現象,但也沒有什麼可怕的。有一個類型的參考,你可以使用它。它有效,這對我來說已經足夠了。”

“這個男孩變成了一個男人!‘這行得通,對我來說已經足夠了’通常是最好的選擇。”

“現在可以用 Java 重做很多事情,但我們需要保持與舊代碼的兼容性。”

“數以萬計流行的完善的庫是當今 Java 最有力的論據。因此,Java 通過保持向後兼容性仍然是最受歡迎的語言,因此它無法引入根本性的創新。”

“好吧,我要用二十一點構建我自己的 Java,然後……”

“好吧,我今天已經累了。下次再見。”

“再見,Rishi,謝謝你給我上了這麼有趣的課。”