Разрешаются ли когда-либо методы экземпляра с использованием привязки stati c? - PullRequest
4 голосов
/ 10 июля 2020

В моих лекциях, касающихся привязки Stati c, приводится пример использования метода экземпляра.

Пример: класс Animal имеет метод:

void dumb() {int x = 0;}

Then

Animal doudi = new Animal(); 
doudi.dumb();

компилятор может напрямую вставить тело {int x = 0;}

Однако, насколько я понимаю, это не метод stati c, поэтому почему он использует привязку stati c как в отличие от динамической c привязки?

Кроме того, на этом веб-сайте говорится, что методы экземпляра разрешаются с использованием динамической c привязки.

Пример здесь не метод экземпляра?

Ответы [ 2 ]

4 голосов
/ 10 июля 2020

Чтобы ответить на вопрос из заголовка, ДА, привязка динамического c не всегда применяется к методам экземпляра.

Есть 3 случая, когда привязка динамического c не выполняется при вызове метода, и это когда метод либо:

  • final - потому что он не может быть переопределен в подтипе, поэтому компилятор уверен, какое тело метода нужно будет выполнить во время выполнения
  • private - поскольку частные методы не наследуются, мы не можем переопределить их. Подтипы могут повторно объявить свой собственный метод с тем же именем и типами параметров (сигнатура), но это не будет рассматриваться как переопределение (вы не можете добавить аннотацию @Override к такому методу в подтипе без ошибки компиляции; вы может изменить свой тип возврата, например, с int на void)
  • static - потому что он вызывается в классе, а не в экземпляре (но это не является предметом вопрос. Короче говоря, даже когда вы напишете someAnimal.staticMethod(), компилятор увидит его, как если бы вы написали Animal.staticMethod())

... так почему он использует stati c привязка в отличие от динамической c привязка

ЭТО НЕТ. В вашем случае, когда вы вызываете doudi.dumb();, компилятор видит, что dumb() не является final, private или static, поэтому он будет подвержен полиморфизму (так что динамическое c связывание).

1 голос
/ 10 июля 2020

Это метод экземпляра !!! Для класса method или attribute необходимо явное использование модификатора static. Вы создаете экземпляр Animal и вызываете метод dump() в этом экземпляре. См. Мой пример:

public class Animal {
    
    static int x = 0; // is an attribute of class
    int y = 0; // is an instance attribute
    
    
    static void myStaticMethod() { // is an method of class
        x++; // increment the class attribute
//      y++; wrong, compilation error !!! y is an instance attribute
    }
    
    void myMethod() { // is an instance method
        y++; // increment the instance attribute
        x++; // increment the class attribute
    }

}

Еще одна особенность: статические c атрибуты / методы назначаются памяти во время компиляции, а нестатистические c атрибуты / методы назначаются памяти при выполнении время. Жизненный цикл атрибута / метода stati c начинается при выполнении программы и заканчивается в конце выполнения, атрибут / метод экземпляра длится (в Java), в то время как счетчик ссылок для этого экземпляра, если выше, то 0, по счетчику ссылок 0 сборщик мусора освобождает выделенную память для этого экземпляра. Посмотрите:

Animal cat = new Animal();

Animal.myStaticMethod();
cat.myMethod();
        
Animal dog = new Animal();

Animal.myStaticMethod();
dog.myMethod();
dog.myMethod();

System.out.println("Animal::x = " + Animal.x);
System.out.println("cat::y = " + cat.y);
System.out.println("dog::y = " + dog.y);

Вывод (без y ++ в myStaticMethod):

Animal::x = 5
cat::y = 1
dog::y = 2
...