"글쎄, 마지막으로 제네릭에 대한 또 다른 작은 교훈입니다."

"이제 유형 삭제를 피하는 방법을 알려 드리겠습니다."

"아. 그것이 내가 알고 싶은 것입니다."

"이미 알고 계시겠지만 Java에는 개체의 클래스에 대한 참조를 저장하는 데 사용되는 클래스 유형이 있습니다. "다음은 몇 가지 예입니다."

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

"아."

"하지만 아마도 당신이 모르는 것은 Class라는 제네릭 클래스도 있다는 것입니다. 그리고 제네릭 클래스 변수는 type 인수에 의해 결정된 유형에 대한 참조만 저장할 수 있습니다.  다음은 몇 가지 예입니다."

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를 사용하면 누군가 실수로 두 가지 다른 유형을 전달할 수 있습니다. 하나는 T 인수로 , 다른 하나는 생성자에게."

"아. 이해합니다. 초자연적인 일도 일어나지 않았지만 끔찍한 일도 없었습니다. 유형에 대한 참조가 있고 사용할 수 있습니다. 작동하고 그것으로 충분합니다."

"소년이 남자가 됩니다! '효과가 있고 그것으로 충분합니다'는 종종 최선의 선택입니다."

"현재 Java에서 많은 것을 다시 실행할 수 있지만 이전 코드와의 호환성을 유지해야 합니다."

"수만 개의 인기 있는 세련된 라이브러리는 오늘날 Java에 대한 가장 강력한 주장입니다. 따라서 Java는 이전 버전과의 호환성을 유지함으로써 가장 인기 있는 언어로 남아 있으므로 급진적인 혁신을 도입할 수 없습니다."

"글쎄, 나는 블랙잭으로 나만의 자바를 만들고..."

"좋아, 오늘부터 벌써 피곤해. 다음 시간까지."

"안녕, 리시. 재미있는 수업을 해주셔서 감사합니다."