基本类型和包装类的内存分配取决于变量位置与创建方式:局部变量的值或引用存栈,成员变量及数组对象均在堆;关键区别在于值语义与引用语义,而非单纯栈堆归属。

Java 中基本类型和包装类的栈与堆分配,不能简单说“基本类型一定在栈、包装类一定在堆”。实际取决于变量的声明位置和创建方式。
局部变量中的基本类型和包装类
在方法内部定义的变量属于局部变量,其引用(或值)存于栈中:
- 基本类型如 int a = 10:变量名 a 和数值 10 都直接存在栈中
- 包装类如 Integer b = 100:栈中存的是引用变量 b,而它指向的对象(即 new 出来的 Integer 实例)默认在堆中 —— 但注意:若值在 -128~127 范围内,JVM 会复用 IntegerCache 中的缓存对象,这些缓存对象本身也是在堆中预先创建好的静态对象
成员变量(字段)的存储位置
类中定义的变量是成员变量,无论基本类型还是包装类,都随对象一起存在堆中:
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
- public int count;:这个 count 的值就放在该对象在堆中的内存布局里
- public Integer id;:堆中存放的是一个引用地址,它指向另一个堆中的 Integer 对象(或 null)
数组和 new 表达式打破“基本类型只在栈”的误解
很多人误以为基本类型只能在栈,其实不然:
立即学习“Java免费学习笔记(深入)”;
- int[] arr = new int[5];:整个数组对象(含 5 个 int 元素)都在堆中分配
- Integer[] nums = new Integer[3];:堆中存的是长度为 3 的引用数组,每个元素初始为 null;后续赋值如 nums[0] = 42,会触发自动装箱,生成新的 Integer 对象(或从缓存取),仍位于堆中
关键区别不在“栈 or 堆”,而在“值语义 or 引用语义”
真正影响行为的是语义差异:
- 基本类型是值语义:赋值是拷贝值,修改不影响原变量
- 包装类是引用语义:赋值拷贝的是引用地址,两个变量可能指向同一对象(尤其缓存范围内);== 比较的是地址,.equals() 才比较数值
- null 只对包装类有意义,基本类型无法表示“不存在”状态

















