Создание экземпляров Java

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
10
0
3 537
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

Интересная ссылка. Как он отвечает на вопрос?

chiccodoro 25.08.2014 14:22
Ответ принят как подходящий

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

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

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

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

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

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

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

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

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

Вы все еще готовы написать пример? Если да, то сделайте это.

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

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

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

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

Все это отчасти интересная информация, но я склонен думать, что части, которые еще не были охвачены ответом Билла, также не отвечают на этот вопрос.

chiccodoro 25.08.2014 14:19

Другие вопросы по теме