Скомпилируется ли код без @Override на переопределенном методе в Java
Что проверяют
Отличаете ли вы механизм переопределения от аннотации, которая его проверяет. Вопрос звучит просто, но по ответу видно, понимаете ли вы, как выбирается реализация во время выполнения, и знаете ли, от какой конкретно ошибки @Override защищает.
Как отвечать
Да, скомпилируется. Переопределение работает по правилам языка: если у метода наследника то же имя и те же типы параметров, что у доступного метода родителя, он переопределяет его независимо от аннотаций. Вызов уходит по фактическому типу объекта, это обычная виртуальная диспетчеризация.
@Override это просьба к компилятору проверить ваше намерение. Она живёт только в исходниках, в байт-код не попадает и на скорость не влияет. Пользы от неё две.
Первая: опечатка в имени или другой тип параметра превращают переопределение в новый метод, и без аннотации это пройдёт молча. Классика:
class Point {
public boolean equals(Point other) { // перегрузка, а не переопределение
return true;
}
}Коллекции продолжат звать equals(Object), и объект потеряется в HashSet. Вторая: если метод в родителе переименуют или удалят, компиляция сломается сразу, а ваш метод не превратится тихо в мёртвый код. На реализациях методов интерфейса аннотация тоже допустима.
Где спотыкаются
Считают аннотацию обязательной и говорят, что без неё будет ошибка компиляции. Ошибка возникает в обратном случае: когда @Override стоит там, где переопределения нет.
Путают переопределение с перегрузкой. Меняют тип параметра и уверены, что переопределили. При этом смена одного лишь типа возврата на несовместимый при тех же параметрах как раз даёт ошибку компиляции, а не тихую подмену.
Думают, что аннотация влияет на выполнение. Реализацию выбирает JVM по фактическому типу объекта, и снятие @Override с готового кода поведение не меняет.