Java-реализация - PullRequest
       6

Java-реализация

10 голосов
/ 21 октября 2008
  1. Когда объект создается в Java, что в действительности происходит в памяти?
  2. Включены ли копии родительских конструкторов?
  3. Почему скрытые элементы данных ведут себя иначе, чем переопределенные методы при приведении?

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

Ответы [ 3 ]

17 голосов
/ 21 октября 2008

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

Ни один из методов никогда не копируется.

«Ссылка» на класс, который его создал, на самом деле является таблицей отправки указателей. Один указатель существует для каждого метода, который доступен классу. Указатели всегда указывают на «правильную» (обычно самую низкую / наиболее конкретную в дереве объектов) реализацию метода.

Таким образом, если у вас есть вызов верхнего уровня для другого метода, но другой метод был переопределен, будет вызван переопределенный метод, потому что именно на него указывает указатель в таблице. Благодаря такому механизму вызов переопределенного метода не должен занимать больше времени, чем метод верхнего уровня.

Таблица указателей + переменные-члены являются «экземпляром» класса.

Переменная проблема связана с совершенно другим механизмом, "пространства имен". Переменные вообще не являются «подклассами» (они не входят в таблицу диспетчеризации), но публичные или защищенные переменные могут быть скрыты локальными переменными. Все это делается компилятором во время компиляции и не имеет ничего общего с вашими экземплярами объекта времени выполнения. Компилятор определяет, какой объект вам действительно нужен, и вставляет ссылку на него в ваш код.

Правила области видимости, как правило, в пользу "ближайшей" переменной. Все, что находится под тем же именем, будет просто проигнорировано (затенено) в пользу более близкого определения.

Чтобы получить более конкретную информацию о распределении памяти, если вам интересно: все «ОБЪЕКТЫ» размещены в «куче» (на самом деле нечто удивительно более эффективное и красивое, чем настоящая куча, но та же концепция.) Переменные всегда указатели --Java никогда не будет копировать объект, вы всегда копируете указатель на этот объект. Распределение указателей переменных для параметров метода и локальных переменных выполняется в стеке, но даже если переменная (указатель) создается в стеке, объекты, на которые они указывают, по-прежнему никогда не размещаются в стеке.

Мне хочется написать пример, но это уже слишком долго. Если вы хотите, чтобы я напечатал пару классов с отношением extends и как их методы и данные влияют на сгенерированный код, я могу ... просто спросить.

2 голосов
/ 21 октября 2008

Я думаю, вы найдете это исчерпывающим примером:

http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html

0 голосов
/ 25 августа 2014
  1. Память выделяется из кучи для хранения всех переменных экземпляра и специфичных для реализации данных объекта и его суперклассов. Специфичные для реализации данные включают в себя указатели на данные классов и методов.

  2. Переменные экземпляра объектов инициализируются в их значения по умолчанию.

  3. Вызывается конструктор для наиболее производного класса. Первое, что делает конструктор, вызывает конструктор для его верхнего регистра. Этот процесс продолжается до тех пор, пока не будет вызван конструктор для java.lang.Object, поскольку java.lang.Object является базовым классом для всех объектов в java. *

  4. Перед выполнением тела конструктора выполняются все инициализаторы переменных экземпляра и блоки инициализации. Затем выполняется конструктор. Таким образом, конструктор для базового класса завершается первым, а конструктор для самого производного класса завершается последним.

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