Почему Java связывает переменные во время компиляции?
рассмотрим следующий пример кода
class MyClass {
public String var = "base";
public void printVar() {
System.out.println(var);
}
}
class MyDerivedClass extends MyClass {
public String var = "derived";
public void printVar() {
System.out.println(var);
}
}
public class Binding {
public static void main(String[] args) {
MyClass base = new MyClass();
MyClass derived = new MyDerivedClass();
System.out.println(base.var);
System.out.println(derived.var);
base.printVar();
derived.printVar();
}
}
это дает следующий результат
base
base
base
derived
вызовы методов разрешаются во время выполнения и вызывается правильный переопределенный метод, как и ожидалось.
Доступ к переменным вместо этого решается во время компиляции, как я позже узнал.
Я ожидал выхода как
base
derived
base
derived
потому что в производном классе переопределение var
тени в базовом классе.
Почему привязка переменных происходит во время компиляции, а не во время выполнения? Это только из соображений производительности?
4 ответа:
причина объясняется в спецификации языка Java в Примере в 15.11, цитируемый ниже:
...
последняя строка показывает, что, действительно, доступ к полю не зависит от класса времени выполнения объекта ссылки; даже если
s
содержит ссылку на объект классаT
, выражениеs.x
относится к
хотя вы можете быть правы в отношении производительности, есть еще одна причина, по которой поля не отправляются динамически: вы не сможете получить доступ к
полиморфное поведение языка java работает с методами, а не с переменными-членами: они разработали язык для привязки переменных-членов во время компиляции.
в java, это по дизайну. Потому что настройка полей, которые будут динамически разрешаться, заставит вещи работать немного медленнее. И на самом деле, нет никакой причины делать это. Так как, вы можете сделать свои поля в любом классе private и доступ к ним с методы, которые динамически решен.
Итак, поля сделаны для лучшего разрешения в время компиляции вместо :)