← Назад к вопросам
Где хранится переменная в методе с типом Integer?
1.3 Junior🔥 191 комментариев
#JVM и управление памятью
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Где хранится переменная типа Integer в методе
Это классический вопрос о том, как Java управляет памятью. Ответ зависит от контекста, и нужно разбираться в разнице между примитивными типами и классами-обёртками.
Stack vs Heap
Примитив int (в stack)
public void method() {
int x = 10; // Переменная x хранится в STACK
// Stack: [x: 10]
}
Примитив int хранится прямо в stack-памяти (что это находится на стеке вызовов потока).
Класс-обёртка Integer (ссылка в stack, объект в heap)
public void method() {
Integer x = 10; // Переменная x — это ССЫЛКА на объект Integer
// Stack: [x: 0x1F4A] (адрес в heap)
// Heap: [0x1F4A: Integer объект с value=10]
}
Переменная x (ссылка) хранится в stack, но сам объект Integer хранится в heap.
Детальное объяснение
1. Переменная Integer x = 10
public void demoInteger() {
Integer x = 10; // Автобоксинг: Integer.valueOf(10)
Integer y = 10; // Может быть тот же объект (из кэша)
Integer z = 1000; // Новый объект (вне диапазона кэша)
System.out.println(x == y); // true (кэш от -128 до 127)
System.out.println(x == z); // false (разные объекты)
}
Что происходит:
- Stack содержит три ссылки:
x,y,z - Heap содержит объекты Integer
xиyмогут указывать на один и тот же объект (Integer кэширует значения от -128 до 127)zуказывает на другой объект
Stack:
┌─────┐
│ x ├───┐
├─────┤ │ (оба указывают на
│ y ├───┼──> на один объект,
├─────┤ │ благодаря кэшу)
│ z ├──┐└───────────────────────┐
└─────┘ │ │
│ Heap: │
│ ┌────────────────────┐ │
└─>│ Integer(10) │ │
│ value: 10 │ │
└────────────────────┘ │
│
┌────────────────────┐ │
│ Integer(1000) │<┘
│ value: 1000 │
└────────────────────┘
2. Параметр метода Integer param
public void processInteger(Integer param) {
// param — это локальная переменная метода
// Ссылка хранится в STACK
// Объект Integer хранится в HEAP
System.out.println(param); // Чтение из heap через ссылку из stack
}
// Вызов
Integer value = 50;
processInteger(value); // Передаём ссылку (не копируем объект)
3. Поле класса Integer
public class User {
private Integer age; // Ссылка хранится в HEAP (как часть объекта User)
public void setAge(Integer age) {
this.age = age; // Сохраняем ссылку на Integer объект
}
}
// Когда создаём пользователя:
User user = new User();
user.setAge(25);
// Память:
// Stack: [user: 0x2F3A] (ссылка на User объект)
// Heap:
// [0x2F3A] User {
// age: 0x3B5C (ссылка на Integer)
// }
// [0x3B5C] Integer {
// value: 25
// }
Тонкости Integer
Кэширование Integer
public class IntegerCaching {
public static void main(String[] args) {
Integer a = 100; // Из кэша
Integer b = 100; // Из кэша
Integer c = new Integer(100); // Новый объект
System.out.println(a == b); // true (один и тот же объект)
System.out.println(a == c); // false (разные объекты)
System.out.println(a.equals(c)); // true (значения равны)
// Кэш работает от -128 до 127
Integer d = 128; // Вне кэша
Integer e = 128; // Вне кэша
System.out.println(d == e); // false!
}
}
Почему это важно
public class Example {
public static void main(String[] args) {
Integer x = new Integer(10);
Integer y = new Integer(10);
Integer z = 10;
// Stack содержит три ссылки
System.out.println(x == y); // false (разные объекты)
System.out.println(y == z); // false или true в зависимости от кэша
System.out.println(x.equals(y)); // true (значения равны)
}
}
Сравнение: int vs Integer
int (примитив)
public void intExample() {
int a = 10; // Stack: значение 10
int b = 10; // Stack: значение 10 (разные переменные)
int c = a; // Stack: копия значения 10
// int сравнивают через ==
System.out.println(a == b); // true
System.out.println(a == c); // true
// Размер: 4 байта
// Диапазон: -2^31 до 2^31-1
}
Integer (класс-обёртка)
public void integerExample() {
Integer a = 10; // Stack: ссылка, Heap: объект Integer
Integer b = 10; // Stack: ссылка, Heap: возможно тот же объект
Integer c = a; // Stack: копия ссылки
// Integer сравнивают через equals()
System.out.println(a == b); // true (из кэша)
System.out.println(a.equals(b)); // true
// Размер: 16-24 байта (overhead объекта)
// Диапазон: -2^31 до 2^31-1
}
Автобоксинг и анбоксинг
public void autoboxing() {
// Автобоксинг: int -> Integer
Integer x = 10; // Эквивалентно Integer.valueOf(10)
// Анбоксинг: Integer -> int
int y = x; // Эквивалентно x.intValue()
// Полный контроль
Integer explicit = Integer.valueOf(20);
int unbox = explicit.intValue();
}
Практический пример: Где находится память
public class MemoryExample {
private Integer fieldInteger; // ССЫЛКА в heap (часть объекта класса)
public void methodExample() {
int localInt = 10; // ЗНАЧЕНИЕ в stack
Integer localInteger = 10; // ССЫЛКА в stack, ОБЪЕКТ в heap
List<Integer> list = new ArrayList<>();
list.add(localInteger); // ССЫЛКА в heap (часть ArrayList)
// В конце метода:
// - localInt и localInteger удаляются из stack
// - если на localInteger нет других ссылок, объект становится eligible для GC
}
public Integer returnInteger() {
Integer result = 100; // ССЫЛКА в stack, ОБЪЕКТ в heap
return result; // Возвращаем ссылку (объект остаётся в heap)
}
}
GC и Integer
public class GCExample {
public static void main(String[] args) {
Integer a = 1000000;
{
Integer b = 2000000; // Новый объект Integer
System.out.println(b); // Используем
} // b выходит из scope, но объект ещё в heap
// GC может собрать этот объект позже
System.gc(); // Просим GC (но это не гарантия)
System.out.println(a); // a всё ещё живой
}
}
Итоговая схема
public void complete() {
// LOCAL VARIABLES (Stack):
int primitiveInt = 5; // ┐ Прямо в stack
Integer wrappedInt = 10; // ├─ Ссылка в stack
Integer[] array = new Integer[3]; // ├─ Ссылка на массив в stack
// HEAP:
// ┌─ Integer объект value=10 (из кэша или новый)
// ├─ Integer[] массив (содержит ссылки)
// └─ Элементы массива (Integer объекты)
}
Выводы
| Переменная | Где хранится | Адрес | Значение |
|---|---|---|---|
| int x | Stack | Непосредственно | 5 |
| Integer x | Stack (ссылка) | 0x1F4A | Объект в heap |
| Integer[] arr | Stack (ссылка) | 0x2A3B | Массив в heap |
| User.age (Integer) | Heap (часть объекта) | - | Ссылка на Integer |
Ключевой момент: Переменная типа Integer x — это ссылка, которая хранится в stack, но указывает на объект Integer, который находится в heap. Это коренной отличает классы-обёртки от примитивных типов.