#java
Есть некий обобщенный интерфейс и класс, его реализующий. interface Contract{ void doIt(T arg); } class Impl implements Contract { @Override public void doIt(Integer arg) { System.out.println("hi"); } } При создании экземпляра Impl и вызове метода следующим образом Contract obj = new Impl(); obj.doIt(42); компилятор вежливо предупреждает, что Unchecked call ... . Я сделал следующий вывод - компилятор не смотрит на то, метод какого класса будет фактически вызван. Вот смотрит он что Contract#doIt(T arg) дергают и предупреждает, что надо бы тип передать. А то что тип передали в класс, который будет всю работу делать от него скрыто. Я правильно всё понял?
Ответы
Ответ 1
Суть тут в том, что вы явно не указали, какой тип в дженерике будет, то есть компилятор не знает об этом, а это чревато ошибкой в рантайме. То есть в приведеном вами коде можно написать так: Contract obj = new Impl(); obj.doIt("123"); //можно передать String и компилятор это съест Но когда вы запустите этот код, вы получите ClassCastException. Почему? Потому что в случае с дженериком в параметре метода компилятор создает так называемый bridge-метод и после компиляции ваш класс Impl будет иметь 2 метода: public void doIt(Integer arg) { System.out.println("hi"); } public void doIt(Object arg) { doIt((Integer) arg); //тут ClassCastException } компилятор вежливо предупреждает, что Unchecked call Собственно, предупреждает, потому что если вы напишите вот так: Contractobj = new Impl(); то передаваемый в этот bridge-метод параметр будет проверен на этапе компиляции и не даст вам выстрелить в ногу. Рекомендую
Комментариев нет:
Отправить комментарий