#java #ооп #generics
Прежде чем отвечать, прошу вдумчиво прочитать и осмыслить вопрос. Итак у нас есть такой код, он скомпилируется и никаких ошибок не будет: public static void main(String[] args) { method(4,"s"); } staticvoid method(K k1, K k2) { } Я думал, что логически ошибка должна быть, ну раз нет, значит такие особенности джавы. Далее, есть такой код: public static void main(String[] args) { method(new ArrayList (), new Object()); } static void method(List k, K k2) { } Этот код уже выдает ошибку компиляции. Компилятор говорит, что я в method (List , java.util.concurrent.Executor) засовываю не то, что надо. Действительно, Object это вам не Executor. Но вот теперь главный мой вопрос почему в первом случае компилятору пофиг, что одному и тому же параметризованному типу присваиваются разные типы данных, а во втором случае компилятор на основе первого аргумента метода вычисляет какой должен быть аргумент второго метода. Я не понимаю какая логика работает в обоих случаях. И еще один не менее важный вопрос, если немного изменить второй пример кода вот так: public static void main(String[] args) { method(new ArrayList (), 150); } static void method(List k, K k2) { } Теперь никакой ошибки не возникает, причем мы можем пихать любые типы данных а компилятору все равно! Мы всего лишь изменили List на List. Тут я уже даже теряюсь, что это значит. Лист который содержит что-то, что наследует К, а что такое К? И почему в итоге нам разрешено класть в параметры метода что угодно (напоминаю, что в предыдущем примере с листом это не разрешено).
Ответы
Ответ 1
Границы для параметров параметризованных типов работают несколько иначе, нежели для простых типов. В первом случае оба типа могут быть приведены к Object, во втором случае тип может быть только либо Object, либо Executor. Если просто тип может быть легко "снижен" до объекта, то дженерики в параметризованных типах такое по умолчанию не позволяют - пока вы не укажете ? extends K, разрешающее использование наследников K, или ? super K, разрешающее использование предков K. В данном случае вы указали ? extends K, что позволяет использовать Object вместо K, таким образом список параметров метода формируется как List, Object. Могу быть в чем-то неправ, точные ответы на эти вопросы содержатся в JLS (Java Language Specification)
Комментариев нет:
Отправить комментарий