「さて、最後に、ジェネリック医薬品に関するもう 1 つの小さなレッスンです。」

「次に、文字の消去を回避する方法を説明します。」

「ああ、それは私が知りたいことなんです。」

「おそらくすでにご存知かと思いますが、Java にはオブジェクトのクラスへの参照を格納するために使用される Class 型があります。いくつかの例を次に示します。」

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

「ああ」

「しかし、おそらくご存知ないのは、Class というジェネリック クラスも存在するということです。そして、ジェネリック 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<T> の代わりに Class を使用した場合、誰かが誤って 2 つの異なる型を渡してしまう可能性があります。1 つは T 引数としてです。 、もう 1 つはコンストラクターに送られます。」

「ああ。わかりました。超自然的なことは何も起こりませんでしたが、ひどいことも起こりませんでした。型への参照があり、それを使用できます。それは機能するので、私にとっては十分です。」

「少年は男になる!『これはうまくいく、私にとってはそれで十分だ』が最善の選択肢である場合が多い。」

「今では多くのことを Java でやり直すことができますが、古いコードとの互換性を維持する必要があります。」

「数万の人気のある洗練されたライブラリは、今日の Java にとって最も強力な議論です。したがって、Java は下位互換性を維持することで最も人気のある言語であり続けるため、抜本的な革新を導入することはできません。」

「それでは、ブラックジャックを使用して独自の Java を構築するつもりですが…」

「分かった、今日はもう疲れた。また次回まで。」

「さようなら、リシ、とても興味深いレッスンをありがとう。」