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

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

ответ

17

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

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

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

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

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

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

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

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

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

+0

Вы по-прежнему готовы написать пример? Если да, то, пожалуйста, сделайте это. – Touchstone 2015-06-09 08:17:40

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

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

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

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

+0

все это интересная информация, но я склонен думать, что части, которые еще не были охвачены ответом Билла, тоже не отвечают на вопрос. – chiccodoro 2014-08-25 10:19:28