— Ну і наостанок ще одна невелика лекція про 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 з блекджеком і …
— Гаразд, я вже втомився за день. Бувай.
— До побачення, Дієго, і дякую за такий цікавий урок.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ