Базовая концепция типа значения и ссылочного типа.
Любой тип переменной (будь то тип значения или ссылочный тип) помещается в стек при объявлении.
Однако, разница между ними заключается в том, что в случае типов значений значение объекта сохраняется в стеке. Принимая во внимание, что в случае ссылочных типов адрес кучи сохраняется в стеке.
Итак, рассмотрим утверждения:
int a;
DecoratorClass decoratorClass;
Теперь, когда выполняются эти операторы, это стек:
STACK:
Variable Value
a 0 // Since ints are assigned to 0 by default
decoratorClass NULL
Теперь, если вы попытаетесь получить доступ к decoratorClass, например, decoratorClass.memberVariable = xyz;
и т. Д., Тогда вы получите исключение NullPointerException.
Это потому, что decoratorClass объявляется только не инициализированным. Он будет инициализирован только при вызове конструктора.
Итак, когда запускается приведенная ниже инструкция:
decoratorClass = new DecoratorClass();
1) Память распределяется в куче в определенном месте (адресе). Объем памяти, выделяемый в байтах, зависит от определения класса (переменные-члены)
HEAP:
xEEEE00
xEEEE01
xEEEE02
xEEEE03
2) Теперь, поскольку объекту выделена некоторая память, стек будет обновляться с помощью адреса памяти
STACK:
Variable Value
a 0 // Since ints are assigned to 0 by default
decoratorClass xEEEE00
Теперь, если вы попытаетесь получить доступ к decoratorClass.memberVariable, вы не получите исключение NullPointer, поскольку экземпляр инициализирован и в стеке назначено место в памяти.
СЕЙЧАС ОТВЕТИТ НА ВАШИ ВОПРОСЫ:
a. Что такое переменная decoratorClass? Ссылка на область памяти, где создается эта переменная, или что-то еще?
И
b. В методе addTest () я инициализирую этот decoratorClass, каким он стал теперь, ссылкой на объект или чем-то еще?
Ans:
Переменная decoratorClass будет помещена в стек при выполнении оператора объявления.
Его значения в стеке (который должен быть адресом в куче) будут нулевыми, так как память еще не распределена в куче.
Память будет выделяться в куче при вызове конструктора.
Стек теперь будет содержать адрес в куче
Позвольте мне ответить d, прежде чем я отвечу c, так как считаю, что вам будет проще понять этот путь.
d. В методе testMethod () я знаю, что копия decoratorClass создана и передана, опять же, это ссылка или что-то еще?
Ans:
С объяснением, которое я дал выше, в методе testMethod (DecoratorClass d) d является локальной переменной для testMethod (). Но каково значение в d (то есть значение в стеке)? Это адрес decoratorClass. Таким образом, локальная переменная d указывает на ту же кучу, и, следовательно, доступ к memberVariable of d будет иметь то же значение, что и доступ к memberVariable для decoratorClass.
Теперь, если вы создадите новый DecoratorClass и назначите его для d, он НЕ ИЗМЕНЯЕТ decoratorClass. Так что d может указывать на EEEE06, но decoratorClass все равно будет указывать на EEEE00.
Теперь давайте перейдем к c.
c. Если это становится ссылкой на объект, то почему мы используем ref в параметрах, которые мы хотим передать по ссылке. Этот вопрос не имеет смысла, если decoratorClass не является ссылкой, а что-то еще.
Ans:
Давайте рассмотрим тот же метод testMethod (ref DecoratorClass d). Поскольку вы передаете d как ref, это уже не локальная переменная, а та же самая переменная.
Теперь, если вы создадите новый DecoratorClass и назначите его для d, он изменит DecoratorClass. Таким образом, d будет указывать на EEEE06, но будет иметь эффект decoratorClass, также указывающего на EEEE06, поскольку обе переменные в стеке являются одинаковыми.
Для получения более подробной информации об объекте pass по ref v / s, проверьте объект pass по значению Память игр
Надеюсь, я достаточно сложен.
Ура!