Ответ
Содержимое переменной в Java зависит от её типа:
-
Для примитивных типов (
int,double,boolean,charи т.д.): Переменная хранит непосредственно значение.int count = 42; // В переменной `count` хранится число 42. boolean flag = true; // В переменной `flag` хранится значение true.Место хранения: Стек (stack frame метода).
-
Для ссылочных типов (классы, интерфейсы, массивы): Переменная хранит ссылку (указатель, адрес) на объект, расположенный в куче (heap).
String message = "Hello"; // `message` хранит ссылку на объект String "Hello". List<Integer> list = new ArrayList<>(); // `list` хранит ссылку на новый объект ArrayList. Object obj = null; // `obj` хранит специальную ссылку null, не указывающую на объект.Место хранения: Сама ссылка — в стеке. Объект, на который она указывает, — в куче.
Важное следствие: При присваивании одной ссылочной переменной другой копируется ссылка, а не объект. Обе переменные начинают указывать на один и тот же объект в памяти.
StringBuilder a = new StringBuilder("Hello");
StringBuilder b = a; // b и a теперь ссылаются на один объект
b.append(" World");
System.out.println(a); // Выведет: "Hello World" Ответ 18+ 🔞
А, слушай, вот эта тема про переменные в Java — она, блядь, как будто простая, а потом бац — и ты уже в жопе, потому что не понял, где что лежит. Ёпта, давай разжую, как есть.
Вот смотри, есть у нас два главных вида переменных, как два сорта говна: одни примитивные, другие — ссылочные. И хранятся они по-разному, сука.
Первые — примитивы. Это как int, double, boolean, char — вся эта хуйня. Тут всё просто, как три копейки. Переменная хранит само значение, прямо в себе. Как будто в кармане заначку держишь.
int count = 42; // В `count` лежит прямо число 42, ни хуя больше.
boolean flag = true; // В `flag` лежит прямо `true`. Всё, пиздец.
И где эта заначка лежит? В стеке, блядь! В том самом стеке метода, который вызвали. Удобно, быстро, и никаких тебе хитрых ссылок.
А теперь вторые — ссылочные. Это уже поинтереснее, ёпта. Сюда входят все классы, интерфейсы и, мать их, массивы. Тут переменная — это не сам объект, а ссылка на него. Как записка с адресом, где этот объект спрятан.
String message = "Hello"; // `message` — это не "Hello", а бумажка с адресом, где "Hello" лежит.
List<Integer> list = new ArrayList<>(); // `list` — адресок на новенький `ArrayList`.
Object obj = null; // А это — пустая бумажка, адреса нет. Просто `null`, нихуя не указывает.
И где же всё это безобразие находится? Сама бумажка-ссылка — в стеке, как и примитив. А вот объект, на который она указывает — тот уже в куче (heap), в этой большой общей помойке памяти. Он там живёт своей жизнью, пока на него кто-то ссылается.
А теперь главный подвох, из-за которого все обоссываются! Когда ты одну ссылочную переменную присваиваешь другой, ты копируешь бумажку с адресом, а не сам объект! Получается, две бумажки ведут к одной и той же хате.
StringBuilder a = new StringBuilder("Hello");
StringBuilder b = a; // Скопировали бумажку! Теперь `b` и `a` смотрят на один и тот же `StringBuilder`.
b.append(" World"); // Пришли по адресу и нахуярили в общий объект.
System.out.println(a); // Выведет: "Hello World". Охуел? А я нет. Так и задумано.
Вот и вся магия, блядь. Запомни: примитивы — это значение в кармане, ссылки — бумажка с адресом на объект в куче. И не путай, а то получишь NullPointerException прямо в ебальник.