На прошлой неделе мы публиковали задачу на знание дженериков от Сергея Галанова. Эту задачу Сергей часто задаёт на собеседованиях, чтобы проверить, понимает ли кандидат, как проходит этап компиляции. По его словам, из 100 человек верно отвечают не более 5–10.
Итак, что же произойдёт с этим кодом?
Правильный ответ — 3.
Почему?
✔️Метод add использует сырой тип List, что отключает проверку дженерик-типов на этапе компиляции. В результате компилятор выдаст только предупреждение, но не ошибку.
✔️Информация о типах стирается после компиляции, поэтому в рантайме System.out.println() вызывает метод toString(), который есть у любого объекта. В консоли выведется 1.
✔️При таком коде программа не пытается привести строку "1" к типу Integer, поэтому исключения ClassCastException не возникает.
А как получить ClassCastException?
Достаточно выполнить любое действие с объектом, например, вместо:
System.out.println(list.get(0));
написать:
Integer o = list.get(0);
System.out.println(o);
Почему задача полезна?
Она помогает понять, что дженерики — это, по сути, синтаксический сахар для компиляции, а в рантайме происходят только действия с объектами. Также важно помнить, что у всех классов есть методы класса Object.