Причина, по которой вы не видите ошибку компиляции, заключается в том, что подпись для contains
в Collection<E>
определяется как:
boolean contains(Object o)
Это верно, Object
. Не contains(<E> o)
.
(Почему они определили это таким образом? Я понимаю, что это для совместимости с версиями Java до Java 5, когда типы коллекций не были обобщенными c. Если они переопределили Метод contains
в Java 5, разрешающий только аргументы <E>
, может привести к поломке большого количества кода, который работал в более ранних версиях Java.)
Итак, что касается компилятора , экземпляр Integer
является подходящим типом аргумента при вызове contains
для List<Long>
.
Разве мы не должны получить ошибку времени компиляции для такой вещи?
Нет. Это действительно Java.
(Если вы имеете в виду «должен» в смысле «было бы лучше, если бы» ... тогда я согласен. Но contains
был определен таким образом по причине, и пути назад нет. )
Что можно сделать, чтобы избежать скрытой ошибки
Попробуйте использовать анализатор кода stati c, например FindBugs или PMD. Я не знаю наверняка, обнаружат ли эти инструменты эту конкретную ошибку, но они могут найти и другие ошибки.
Кроме этого:
- Еще тестирование.
- Измените свою кодовую базу, чтобы использовать пользовательский тип для идентификаторов. Тот, который не может быть автоматически / распакован. (Много работы, и лекарство может быть хуже болезни ... как говорится.)