Страницы

Поиск по вопросам

воскресенье, 21 октября 2018 г.

Java: объясните поведение компилятора

Здравствуйте! Столкнулся со странным поведением компилятора, объясните пожалуйста, почему происходит вывод разных строк. class EntityModel{ public String name; public EntityModel(){ this.name = "EntityModel"; } public String getName(){ return this.name; } } class Model1 extends EntityModel{ public String name; public Model1(){ this.name = "Model1"; }
@Override public String getName(){ return this.name; } } Вызов: EntityModel m = (EntityModel)new Model1(); System.out.println(m.name); System.out.println(m.getName()); Вывод: EntityModel Model1 Код на ideone.com Почему обращение к полю на прямую и через геттер дают разные результаты?


Ответ

Хе :) Если коротко, то в Java методы виртуальные, а поля — нет. То есть, привязка метода к имени метода производится на этапе выполнения в соответствии с настоящим, динамическим типом объекта, а вот привязка поля — статическая, производится на этапе компиляции. Так сделано потому, что выставлять наружу открытое поле всё равно очень плохая практика, поэтому доступ к полям можно ускорить за счёт точного определения поля во время компиляции. А вот вызывая публичный метод, программист не ожидает вызова не самого «свежего» метода, так что здесь логичнее виртуальный вызов. (Впрочем, архитекторы C# считают не так, но это уже вопрос дизайна языков.) Это всё ещё один аргумент к тому, чтобы делать все поля private, и получать доступ к ним лишь через getter.

Комментариев нет:

Отправить комментарий