Статический Vs. Динамическая привязка в Java

в настоящее время я выполняю задание для одного из моих классов, и в нем я должен привести примеры, используя синтаксис Java, из static и динамическое связывание.

Я понимаю основную концепцию, что статическая привязка происходит во время компиляции, а динамическая привязка происходит во время выполнения, но я не могу понять, как они на самом деле работают.

Я нашел пример статической привязки в интернете, который дает этот пример:

public static void callEat(Animal animal) {
    System.out.println("Animal is eating");
}

public static void callEat(Dog dog) {
    System.out.println("Dog is eating");
}

public static void main(String args[])
{
    Animal a = new Dog();
    callEat(a);
}

и что это напечатает "животное ест", потому что вызов callEat использует статическое связывание, но я не уверен, что почему это считается статической привязкой.

до сих пор ни один из источников, которые я видел, не смог объяснить это таким образом, что я могу следовать.

6 ответов


С Javarevisited сообщение в блоге:

вот несколько важных различий между статической и динамической привязкой:

  1. статическая привязка в Java происходит во время компиляции, в то время как динамическая привязка происходит во время выполнения.
  2. private, final и static методы и переменные используют статическую привязку и связаны компилятором, в то время как виртуальные методы связаны во время выполнения на основе объекта времени выполнения.
  3. статическая привязка использует Type (class в Java) информация для привязки, в то время как динамическая привязка использует объект для разрешения привязки.
  4. перегруженные методы связаны с использованием статической привязки, а переопределенные методы связаны с использованием динамической привязки во время выполнения.

вот пример, который поможет вам понять как статическую, так и динамическую привязку в Java.

пример статической привязки в Java

public class StaticBindingTest {  
    public static void main(String args[]) {
        Collection c = new HashSet();
        StaticBindingTest et = new StaticBindingTest();
        et.sort(c);
    }
    //overloaded method takes Collection argument
    public Collection sort(Collection c) {
        System.out.println("Inside Collection sort method");
        return c;
    }
    //another overloaded method which takes HashSet argument which is sub class
    public Collection sort(HashSet hs) {
        System.out.println("Inside HashSet sort method");
        return hs;
    }
}

выход: внутри коллекция метода sort

пример динамической привязки в Java

public class DynamicBindingTest {   
    public static void main(String args[]) {
        Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
        vehicle.start(); //Car's start called because start() is overridden method
    }
}

class Vehicle {
    public void start() {
        System.out.println("Inside start method of Vehicle");
    }
}

class Car extends Vehicle {
    @Override
    public void start() {
        System.out.println("Inside start method of Car");
    }
}

выход: внутри метода запуска автомобиля


подключение вызова метода к телу метода называется привязкой. Как сказал Маулик, "статическая привязка использует информацию типа (класса в Java) для привязки, а динамическая привязка использует объект для разрешения привязки."Итак, этот код:

public class Animal {
    void eat() {
        System.out.println("animal is eating...");
    }
}

class Dog extends Animal {

    public static void main(String args[]) {
        Animal a = new Dog();
        a.eat(); // prints >> dog is eating...
    }

    @Override
    void eat() {
        System.out.println("dog is eating...");
    }
}

произведет результат:собака ест... потому что он использует ссылку на объект, чтобы найти, какой метод использовать. Если мы изменим приведенный выше код на этот:

class Animal {
    static void eat() {
        System.out.println("animal is eating...");
    }
}

class Dog extends Animal {

    public static void main(String args[]) {

        Animal a = new Dog();
        a.eat(); // prints >> animal is eating...

    }

    static void eat() {
        System.out.println("dog is eating...");
    }
}

он произведет:животное ест... поскольку это статический метод, он использует Type (в данном случае Animal) для разрешения вызова статического метода. Помимо статических методов частные и конечные методы используют один и тот же подход.


компилятор знает только, что тип "а"Animal; это происходит во время компиляции, из-за чего оно называется статической привязкой (перегрузкой метода). Но если это динамическая привязка, то она вызовет Dog метод класса. Вот пример динамической привязки.

public class DynamicBindingTest {

    public static void main(String args[]) {
        Animal a= new Dog(); //here Type is Animal but object will be Dog
        a.eat();       //Dog's eat called because eat() is overridden method
    }
}

class Animal {

    public void eat() {
        System.out.println("Inside eat method of Animal");
    }
}

class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("Inside eat method of Dog");
    }
}

выход: Внутри ешьте метод собаки


существует три основных различия между статической и динамической привязкой при разработке компиляторов и как переменные и процедуры переданы время работы окружающая среда. Эти различия заключаются в следующем:

Статическое Связывание: в статической привязке обсуждаются три следующие проблемы:

  • определение процедуры

  • объявление a имя(переменная, и т. д.)

  • область объявления

Динамическое Связывание: три проблемы, которые встречаются в динамической привязке, следующие:

  • активация процедуры

  • привязка имени

  • время жизни привязки


со статическим методом в Родительском и дочернем классе: статическая привязка

public class test1 {   
    public static void main(String args[]) {
        parent pc = new child(); 
        pc.start(); 
    }
}

class parent {
    static public void start() {
        System.out.println("Inside start method of parent");
    }
}

class child extends parent {

    static public void start() {
        System.out.println("Inside start method of child");
    }
}

// Output => Inside start method of parent

Динамическое Связывание :

public class test1 {   
    public static void main(String args[]) {
        parent pc = new child();
        pc.start(); 
    }
}

class parent {
   public void start() {
        System.out.println("Inside start method of parent");
    }
}

class child extends parent {

   public void start() {
        System.out.println("Inside start method of child");
    }
}

// Output => Inside start method of child

потому что компилятор знает, что связывание во время компиляции. Например, если вы вызываете метод на интерфейсе, компилятор не может знать, и привязка разрешена во время выполнения, потому что фактический объект, имеющий метод, вызываемый на нем, может быть одним из нескольких. Поэтому это среда выполнения или динамическая привязка.

ваш вызов привязан к классу Animal во время компиляции, потому что вы указали тип. Если вы передали эту переменную в другой метод где-то иначе никто не знал бы (кроме вас, потому что вы написали это), какой фактический класс это будет. Единственный ключ к разгадке-объявленный тип животного.