Карта / ООП / static / dynamic binding

static / dynamic binding

Binding — это момент, когда Java решает, какой именно метод вызвать. Бывает два вида, и разница в том, когда принимается решение.

Static binding (статическое связывание) — решение принимается на этапе компиляции. Так работают перегруженные методы и static-методы:

void print(String s) { ... }
void print(int n) { ... }

print("hi");   // компилятор уже знает: вызовется print(String)

Dynamic binding (динамическое связывание) — решение принимается в рантайме, по реальному типу объекта. Так работают переопределённые методы:

Animal a = new Dog();
a.makeSound();   // вызовется Dog.makeSound() — несмотря на то, что тип переменной Animal

Подробнее про сам механизм переопределения — в теме «Перегрузка и переопределение».

Копнуть глубже

Ключевое наблюдение: при dynamic binding важен реальный тип объекта в куче, а не тип переменной, через которую к нему обращаются:

Animal a = new Dog();   // тип переменной: Animal, реальный тип объекта: Dog
a.makeSound();           // вызовется версия Dog — по реальному типу

Это и есть полиморфизм в действии: один и тот же код (a.makeSound()) ведёт себя по-разному в зависимости от того, какой объект реально лежит в переменной.

static, private и final методы всегда решаются статически — их нельзя переопределить, значит выбирать не из чего, JVM точно знает, какой метод вызвать, ещё на компиляции.

Под капотом

Для dynamic binding у каждого класса с переопределяемыми методами JVM строит виртуальную таблицу методов (vtable) — список указателей на реальные реализации методов этого класса. Вызов a.makeSound() в байт-коде превращается в invokevirtual — инструкцию «посмотри в vtable реального класса объекта и вызови, что там лежит».

Это работает быстро (поиск по индексу в таблице, не перебор), но всё же чуть медленнее, чем invokestatic для static binding, где адрес метода уже известен заранее и просто «зашит» в байт-код. На практике эта разница пренебрежимо мала для подавляющего большинства программ.

🎤 Закрыл тему, если можешь объяснить:
• разницу static и dynamic binding и какие методы решаются статически;
• почему важен реальный тип объекта, а не тип переменной (если дошёл до 2-го слоя).