Что такое статическое и динамическое связывание (раннее и позднее связывание)
Что проверяют
Различаете ли вы то, что решает компилятор, и то, что решает виртуальная машина. За вопросом почти всегда идёт задача с подвохом: перегрузка, сокрытие статического метода или обращение к полю через ссылку родительского типа.
Как отвечать
Раннее связывание это выбор по статическим типам на этапе компиляции. Так разрешаются перегрузки, обращения к полям, вызовы методов static, private, final и конструкторов. Позднее связывание это выбор реализации по фактическому классу объекта во время выполнения, на нём держится полиморфизм.
Parent p = new Child();
p.show(); // реализация Child: решает машина
int n = p.value; // поле Parent: решил компилятор
Parent.stat(); // статический метод скрывается, а не переопределяетсяВажная тонкость: сигнатуру метода компилятор выбирает всегда и записывает в байт-код, а конкретную реализацию обычного метода подставляет уже машина через таблицу виртуальных вызовов. Поэтому вызов обычного метода остаётся поздним даже тогда, когда тип переменной совпадает с типом объекта.
Хорошо звучит практический вывод: позднее связывание даёт расширяемость, раннее даёт предсказуемость и проверку на компиляции. Отсюда и правило проектирования: вспомогательные операции делают статическими, а точками расширения оставляют виртуальные методы, осознанно и с документацией.
Где спотыкаются
Называют статическим связыванием вызов обычного метода у переменной точного типа. Механизм тот же виртуальный, просто реализация одна. Оптимизатор действительно умеет встроить такой вызов, но это работа машины во время исполнения, а не решение компилятора.
Ждут от статического метода переопределения. Метод с той же сигнатурой в наследнике не переопределяет, а скрывает родительский, и вызов через ссылку родительского типа уйдёт в родительскую реализацию, даже если объект создан дочерним классом. С полями ровно то же самое.
Раздувают разницу в скорости. Разные инструкции байт-кода действительно есть, но для вызова с единственной реализацией машина встраивает код, и разница исчезает. Выбирать между статическим и виртуальным методом ради производительности значит оптимизировать то, чего нет.