Generics: ? wildcard

Модуль 2. Java Core
5 уровень , 3 лекция
Открыта

— Ну, и напоследок еще одна маленькая лекция по 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 с блекджеком и …

— Ладно, я уже подустал за день. Давай до свидания.

— До свидания, Риша, и спасибо за такой интересный урок.

Комментарии (38)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Виталий Уровень 31
13 декабря 2025
Лекция по дженерикам - 💩. Зачем, почему, как правильно использовать?
Andrei Miroshnichenko Уровень 1
5 августа 2025
как только попадается сложная тема, так авторы по полной обсираются. в очередной раз приходится обращаться к чату и гуглу
Иван Уровень 112
26 марта 2025
Тот кто писал эти лекции, не пытался сам их прочитать, материал подан ужасно. Несуразные радуга цветов и "диалог", и полное непонимание происходящего у того, кто читает
Arthur Kozlov Уровень 115
24 марта 2025
Перед тем как нажать кнопку "Открыть следующую лекцию", слышу знакомый саундтрек и понимаю что еще вернусь сюда.
Денис Уровень 68
25 января 2025
В 3-й задаче я сделал так: public static String concat(List<? extends Object> list) { StringBuilder builder = new StringBuilder(); for (Object obj : list) { builder.append(obj); } return builder.toString(); }
Кирилл Уровень 115
21 января 2025
По всему уровню ничего не понятно. Тема не раскрыта, от слова совсем. Чем дальше, тем, видимо, хуже будет подан материал. Либо к этому моменту мы должны уже иметь общее понимание как программировать и такие темы должны быть понятны и без разжевывания (лично у меня такого нет), либо разработчики учебных материалов начали халтурить.
Денис Уровень 68
22 января 2025
Да, тема с дженериками с ходу не зашла, придётся несколько раз перечитывать. Местами непонятно совсем.
Артем Уровень 48
19 февраля 2025
+1 Что-то совсем печально даются мне эти дженерики...
Виктор Ш Уровень 72
20 марта 2025
Пишется весело. Но мне трудно уследить за нитью. Примеры очень абстрактны.
Максим Уровень 115
17 января 2025
— Как ты уже наверное знаешь, в Java есть тип Class, который используется, чтобы хранить ссылку на объект класса. Нет, первый раз слышу... Ничего не понятно.
6 октября 2024
Деньги заплатили и ладно, объяснять не обязательно. Диалог дурацкий, лучше больше объяснений.
Никита Уровень 102
17 июля 2024
ОЧень хорошие задачи и отвратительная лекция!
Тимур Уровень 109 Expert
28 апреля 2024
Сначала не понял, а потом как понял.. 😬
Дмитрий Уровень 66 Expert
3 июля 2024
Сначала не понял, а потом как опять не понял.. 😬