Вы путаете динамический вызов с динамическое связывание ..
Первый позволяет контроллеру типов принимать программы, в которых вы не уверены, будет ли метод присутствовать на объекте во время выполнения, тогда как динамическое связывание просто выбирает правильную реализацию в соответствии с типом времени выполнения объекта но с сохранением статической проверки типов .
Что это значит?
Это означает, что в вашем примере Java будет вызывать реализацию для объекта B
, поскольку тип времени выполнения переменной objA
равен B
; и он скомпилируется, потому что знает, что B
- это A
, поэтому вызов метода не будет завершен неудачно во время выполнения (objA
наверняка будет иметь реализацию F
). *
Вместо этого при динамическом вызове он не будет проверять во время компиляции, что тип объекта, для которого вы вызываете F
, содержит этот метод, конечно, он вызовет исключение, если во время выполнения метод не будет доступен на указанном объекте.
Только для мелочей: функция invokedynamic
будет добавлена с Java7, потому что многие языки сценариев были написаны для работы поверх JVM, а отсутствие функции динамического вызова вынудило разработчиков этих языков добавить средний уровень между скрипт и реальная JVM, которая заботится о динамическом вызове с использованием отражения. Конечно, такой подход приводит к большим накладным расходам (подумайте о MetaClass
Грови), поэтому Sun решила им помочь.