Правда ли, что каждая привязка во время выполнения была статической привязкой во время компиляции? - PullRequest
1 голос
/ 01 октября 2019

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

class A
{
    void show()
    {
        System.out.println("From A");
    }
}
class B extends A
{
    void show()
    {
        System.out.println("From B");
    }
}
class Main
{
    public static void main(String[] quora)
    {
        A a1 = new A();
        A a2 = new B();

        a1.show(); //line 1
        a2.show(); //line 2
    }
}

В приведенном выше примере мы можем видеть, что во время компиляции и Line1, и line2 будут обрабатываться статическим связыванием, и они будут связаны с показом метода класса A (поскольку тип ссылки - A). Но во время выполнения вызов разрешается, и line1 ссылается на метод класса A show (), а line2 - на метод класса B, т. Е. Тип объекта или, можно сказать, динамическое связывание.

Так что мой главныйнамерение состоит в том, чтобы знать следующее.

  1. Всегда ли динамическое связывание всегда происходит после статического связывания? или я что-то не так понимаю?

  2. Если это правда, то правда ли, что каждый метод динамически связан во время выполнения?

  3. Можем ли мы обобщить это?

1 Ответ

1 голос
/ 01 октября 2019

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

Рассмотрим:

class A
{
    void f(Object o)
    {
        System.out.println("From A");
    }
}
class B extends A
{

    void f(Object o)
    {
        System.out.println("From B (Object)");
    }

    void f(String s)
    {
        System.out.println("From B (String)");
    }
}

Ивы делаете:

A a = new B();
a.f("");

Что происходит? Во время компиляции компилятор выбрал перегрузку f(Object) из-за типа a, являющегося A (есть только один метод на выбор!). Затем во время выполнения, поскольку a фактически ссылается на экземпляр B, вызывается реализация B перегрузки f(Object), выводя From B (Object). Одно заблуждение, которое я видел, - ожидать, что результат будет From B (String). Это неправильно, потому что компилятор не знает о существовании этой перегрузки на a.

Всегда ли динамическое связывание всегда происходит после статического связывания?

Как мыКак видно из результатов приведенного выше кода, ответ - да. Статическое связывание происходит во время компиляции, динамическое связывание происходит во время выполнения, поэтому первое всегда происходит первым.

Если это правда, то правда ли, что каждый метод динамически связан во время выполнения?

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

несмотря ни на что, всегда будет статическое связывание итогда динамическое связывание для каждого вызова метода?

Да, но иногда эти два процесса могут идти очень быстро, потому что вариантов очень мало. Вам, вероятно, не нужно делать «выбор» в динамическом связывании, когда класс, для которого вы вызываете метод, является конечным классом, не так ли?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...