Два метода с одинаковым именем в java


Я заметил, что если у меня есть два метода с одинаковым именем, первый принимает SomeObject, а второй принимает объект, расширяющий SomeObject, когда я вызываю метод с SomeOtherObject, он автоматически использует тот, который принимает только SomeObject. Если я приведу SomeOtherObject к SomeObject, используется метод, который принимает SomeObject, даже если объект является экземпляром SomeOtherObject. Это означает, что метод выбирается при компиляции. Почему?

3 3

3 ответа:

Вот как работает разрешение перегрузки метода в Java: метод выбирается во время компиляции.

Для всех уродливых деталей смотрите спецификацию языка Java §15.12.

Это означает, что метод выбирается при компиляции.

Да, вы правы. Вот что это значит.

Почему?

Я могу назвать четыре причины, по которым они разработали Java таким образом:
  • Это согласуется с тем, как работают другие статически типизированные языки OO, поддерживающие перегрузку. Именно этого ожидают люди, пришедшие / пришедшие из мира C++. (Это было особенно важно в первые дни существования Явы ... хотя и не так теперь многое.). Стоит отметить, что C# обрабатывает перегрузку таким же образом.

  • Это эффективно. Разрешение перегрузок метода во время выполнения (на основе фактических типов аргументов) сделало бы перегруженные вызовы метода дорогими.

  • Это дает более предсказуемое (и, следовательно, более понятное) поведение.

  • Это позволяет избежать проблемы хрупкого базового класса, когда добавление нового перегруженного метода в базовый класс вызывает неожиданные проблемы в существующем производный класс.

Ссылки:

Да, функция, которая будет выполняться, определяется во время компиляции! Таким образом, JVM не имеет представления о фактическом типе объекта во время компиляции. Он знает только тип ссылки, которая указывает на объект, заданный в качестве аргумента функции.

Для получения более подробной информации вы можете посмотреть на выбор наиболее конкретного метода в спецификации Java.