Разница между ранним и поздним связыванием в Java
В этом посте будет обсуждаться разница между ранним и поздним связыванием (статическим и динамическим связыванием) в Java.
Связывание обычно относится к отображению одной вещи на другую. В контексте скомпилированных языков программирования привязка — это связь вызова метода с определением метода. Проще говоря, когда метод вызывается в Java, элемент управления программы привязывается к адресу памяти, где этот метод определен.
В Java есть два типа связывания — раннее (или статическое) связывание и позднее (или динамическое) связывание. В этом посте представлен обзор различий между ними.
- The рано привязка происходит во время компиляции и поздно привязка происходит во время выполнения.
- При раннем связывании определение метода и вызов метода связываются во время компиляции. Это происходит, когда вся информация, необходимая для вызова метода, доступна во время компиляции. В отличие от раннего связывания, вызовы методов не разрешаются до времени выполнения в позднем связывании, поскольку мы не можем определить всю информацию, необходимую для вызова метода, во время компиляции. Таким образом, определение метода и вызов метода не связаны до времени выполнения.
- Обычные вызовы методов и вызовы перегруженных методов являются примерами раннего связывания, а отражение и переопределение методов (полиморфизм времени выполнения) — примерами позднего связывания.
- Привязка частных, статических и конечных методов происходит во время компиляции, поскольку их нельзя переопределить.
- Поскольку вся информация, необходимая для вызова метода, доступна до начала выполнения, раннее связывание приводит к более быстрому выполнению программы. В то время как для более поздней привязки вызов метода не разрешается до времени выполнения, что приводит к несколько более медленному выполнению кода.
- Основным преимуществом позднего связывания является его гибкость, поскольку один метод может обрабатывать различные типы объектов во время выполнения. Это значительно уменьшает размер кодовой базы и делает код более читабельным.
Объясните наглядно разницу раннего и позднего связывания методов.
Позднее связывание методов это когда имеется ссылочная переменная, и в зависимости от того экземпляр какого класса будет создан, и будет вызван соответствующий метод. А как насчет раннего связывания в чем отличие?
Отслеживать
задан 28 июн 2013 в 15:06
1,996 5 5 золотых знаков 29 29 серебряных знаков 48 48 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Раннее связывание — это когда метод, который будет вызван, известен во время компиляции, например, вызов статического метода.
Кстати, то что вы называете поздним связываением, есть скорее dynamic dispatch.
Позднее связывание — это когда вызов метода может быть осуществлен только во время выполнения и у компилятора нет информации, чтобы проверить корректность такого вызова. В java это можно сделать при помощи рефлексии.
Отслеживать
ответ дан 28 июн 2013 в 15:14
misha-nesterenko misha-nesterenko
956 5 5 серебряных знаков 8 8 бронзовых знаков
Можно пример позднего связывания
28 июн 2013 в 15:36
Вот пример: Object a = . // какое-то присваивание a.toString(); На этапе компиляции мы не знаем, какого типа объект a . Он может быть как собственно Object , так и любым его наследником, в котором метод toString() переопределён. Именно на этапе выполнения определяется тип a и вызывается toString() из того класса, какого типа объект a . Это и есть позднее связывание.
28 июн 2013 в 15:54
@JAVAVladuxa, посмотри en.wikipedia.org/wiki/Late_binding#Late_binding_in_Java
28 июн 2013 в 18:11
Раннее связывание, как было отмечено выше, происходит на этапе компиляции. Оно применяется при вызове обычных методов (не виртуальных).
Позднее связывание напротив происходит во время выполнения. Выполняется оно при вызове виртуальных функций класса-потомка для определения того, какой именно метод следует вызывать.
Исходя из того, что раннее связывание выполняется на этапе компиляции, а позднее — в рантайме, первый вариант обладает лучшим быстродействием, однако второй необходим для реализации полиморфизма.
По поводу Java могу сказать, что там, если не ошибаюсь, ко всем методам по умолчанию применяется позднее связывание (если они не помечены модификатором final) в отличие от, скажем, С++, где по умолчанию применяется раннее связывание. Еще для большего понимания вопроса почитайте про таблицу виртуальных методов
З.Ы. с Java близко не знаком, поэтому точно не могу сказать, насколько там применим термин «функция»
Связывание в Java: динамическое – позднее, статическое – раннее
Ассоциация вызова метода с телом метода известна как связывание в Java. Есть два вида связывания.
Статическое связывание
В статическом связывании вызов метода связан с телом метода во время компиляции. Это также известно как раннее связывание. Делается с помощью статических, частных и, окончательных методов.
Пример
class Super < public static void sample()< System.out.println("This is the method of super class"); >> Public class Sub extends Super < Public static void sample()< System.out.println("This is the method of sub class"); >Public static void main(String args[]) < Sub.sample() >>
Итог
This is the method of sub class
Динамическое связывание
В динамическом связывании вызов метода связан с телом метода во время выполнения. Это также известно как позднее связывание. Делается с помощью методов экземпляра.
Пример
class Super < public void sample()< System.out.println("This is the method of super class"); >> Public class extends Super < Public static void sample()< System.out.println("This is the method of sub class"); >Public static void main(String args[]) < new Sub().sample() >>
Итог
This is the method of sub class
Ниже перечислены существенные различия.
- Это происходит во время компиляции.
- Это наблюдается в частных, статических и конечных методах.
- Он известен как раннее связывание.
- Происходит во время выполнения.
- Это наблюдается в методах экземпляра.
- Он известен как позднее связывание.
Средняя оценка 1.4 / 5. Количество голосов: 60
Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.
Или поделись статьей
Видим, что вы не нашли ответ на свой вопрос.
Помогите улучшить статью.
Напишите комментарий, что можно добавить к статье, какой информации не хватает.
Раннее и позднее связывание Java?
1. Что это такое? (возможно на конкретных примерах (ссылки))
2. Основное, что нужно знать об этом, чтобы понимать
3. Зачем это нужно?
- Вопрос задан более трёх лет назад
- 8698 просмотров
2 комментария
Оценить 2 комментария
Гуглить не умеете?
Nikita @NeToster Автор вопроса
Vladislav Kovalev: Умею, конечно. Цель создания вопроса, получить доступный ответ простыми словами. Человек который в этом разобрался, возможно расскажет свое понимание на данном ресурсе
Решения вопроса 0
Ответы на вопрос 2
Пишу комментарии в комментарии, а не в ответы
Этим и полезно знание знакомство с C++ (=
Суть в чем: куда-то в память загружается объект-тип (не экземпляр с данными, а именно представление типа), в котором физически располагается код методов. У каждого экземпляра классов есть ссылка на свой объект-тип. Когда тип ссылки на объект совпадает с его типом, то все просто: мы знаем, что метод можно найти напрямую. Открываются перспективы для оптимизации компилятора: подстановка конкретного адреса метода или даже инлайнинг (когда вызов метода заменяется непосредственно на код из метода, чтобы не тратить такты на передачу параметров). Это раннее связывание.
Если же у нас возможен полиморфный вызов (переменная-ссылка может указывать на объект-наследник, у которого может быть переопределение родительского метода), то нужно узнать точно какого типа объект, чтобы вызвать подходящее определение метода из нужного типа. Увы, это мы узнаем только в рантайме, поэтому компилятор не поможет оптимизировать этот процесс. Это позднее связывание.
Во многих Си-подобных языках (C++, C# и т.п.) в угоду производительности используется раннее связывание по умолчанию: полиморфные методы должны явно помечаться программистом ключевым словом virtual (иначе будет вызываться метод из типа переменной-ссылки, не полиморфно), в Java же в угоду читаемости кода используется позднее связывание по умолчанию: все методы неявно «virtual», так что качество связывания отдается на откуп компилятору.
Конечно, есть возможность пометить метод ключевым словом final , что запретит переопределять метод в наследниках, т.е. у компилятора появятся все полномочия жестко вбить необходимый адрес метода в точку вызова без страха, ибо альтернативных версий метода в наследниках просто быть не может.
(В С++11 также есть ключевое слово final , а в C# — sealed )