Хранение переменной зависит от того, является ли переменная локальной переменной или переменной экземпляра .
Локальные переменные хранятся в стеке . Экземпляры и статические переменные хранятся в куче .
Позвольте мне объяснить это на примере. Допустим, у нас есть переменная экземпляра animal некоторого пользовательского класса Animal.
Животное животное = новая собака ();
Здесь животное - просто ссылка и находится в стеке . Фактическому объекту выделяется память на куче . Это эталонное животное будет указывать на память объекта, выделенную в куче. Так что если у вас есть 3 ссылки, указывающие на один и тот же объект.
Animal animal1 = new Dog();
Animal animal2 = new Dog();
Animal animal3 = new Dog();
Все три ссылки будут в стеке. Когда я говорю ссылка, это просто указатель, указывающий на объект в куче . С точки зрения памяти, эта ссылка содержит адрес (на самом деле здесь немного больше абстракции) объекта в куче. Так 4 байта на 32 бита и 8 байтов на 64 бита . Только когда все три ссылки разыменовываются , т.е. они больше не находятся в области видимости (или, скорее, больше не указывают на исходный объект), тогда только сборщик мусора может освободить память, выделенную объекту в куче.
Существует небольшое изменение, когда мы храним примитивные типы или строковые литералы. Если вы явно не создадите их объект с помощью оператора new (), они создаются и хранятся в области permGen в Heap.
Так что обе ссылки firstString и secondString в
String firstString = "Stack";
String secondString = "Stack";
будет указывать на тот же объект в пуле строк. Он будет указывать на разные объекты, когда мы создаем их с помощью new ().