— Ну і наостанок ще одна невелика лекція про Generic.

Зараз я тобі розповім, як оминати «стирання типів» (Type erasure).

— Ага. Мені теж хочеться це знати.

—Як ти вже напевно знаєш, Java має тип Class, який використовується, щоб зберігати посилання на об'єкт класу. Приклади:

Приклади
Class clazz = Integer.class;
Class clazz = String.class;
Class clazz = "abc".getClass();

— Ага.

Але чого ти, напевно, не знаєш, так це того, що є ще один клас Class, який є Generic’ом. І змінні цього Generic Class’у можуть зберігати лише посилання на тип, що був типом-параметром. Приклади:

Приклади
Class<Integer> clazz1 = Integer.class; //усе чудово працює
Class<String> clazz2 = Integer.class; //помилка компіляції.
Class<String> clazz1 = String.class; //усе чудово працює
Class<String> clazz2 = int.class; //помилка компіляції.
Class<? extends String> clazz1 = "abc".getClass(); //усе чудово працює
Class<Object> clazz2 = "abc".getClass(); //помилка компіляції.

— А чому воно так працює?

— Справа в тому, що значення поля class у типу Integer (тобто у Integer.class) – це насправді об'єкт типу Class<Integer>.

Але давай підемо далі.

Так ось, користуючись тим фактом, що Class<T> — це Generic, і тим, що змінна його типу може зберігати значення лише типу 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); // ось тут передається тип!
Tiger tiger = zoo.createNewAnimal();

Це не мегахитра комбінація – ми просто передаємо посилання на потрібний тип. Але якби ми просто користувалися Class замість Class<T>, то хтось міг би помилково передати туди два різні типи – один як параметр T, інший – до конструктора.

— Ага. Розумію. Нічого надприродного не сталося, і страшного – також. Посилання на тип є, користуватися ним можна, працює – і добре.

— Ось, чую слова «не хлопчика, а чоловіка!» Працює і добре – це найбільш оптимальний варіант.

Дуже багато всього можна було б переробити в Java, але потрібно зберігати сумісність зі старим кодом.

Саме десятки тисяч популярних налагоджених бібліотек – це найвагоміший аргумент на користь Java сьогодні. Отже, зберігаючи зворотну сумісність, Java залишається найпопулярнішою мовою, і тому може впроваджувати радикальні нововведення.

— А я зроблю свою Java з блекджеком і …

— Гаразд, я вже втомився за день. Бувай.

— До побачення, Дієго, і дякую за такий цікавий урок.