Java中变量在虚拟机栈的存放方式是:基本类型直接存值,对象类型只存地址。基本类型如int、char等值完整写入栈帧局部变量表,固定大小、编译期确定空间;对象类型如String仅存指向堆中对象的引用地址,真实数据在堆中分配;赋值时基本类型为值拷贝,对象类型为引用拷贝;==对基本类型比较数值,对对象类型比较地址,内容比较需用equals()。

Java 中变量在虚拟机栈里的存放方式,核心差异在于:基本类型直接存值,对象类型只存地址。
栈中怎么放基本类型
基本类型(如 int、char、boolean)的值本身被完整写入栈帧的局部变量表。比如 int x = 100;,栈里就实实在在存着数字 100,不涉及其他内存区域。
- 每个基本类型有固定大小(如 int 占 4 字节),编译期就能确定空间,适合栈的快速分配与释放
- 成员变量中的基本类型,若未用 static 修饰,会随所在对象一起存在堆中;但局部变量一定在栈中
- 默认值明确:如 int 默认为 0,boolean 默认为 false
栈中怎么放对象类型
对象类型(如 String、ArrayList、自定义类实例)在栈中只存一个引用——也就是指向堆中真实对象的内存地址。
- 声明
String s = new String("hello");时,栈中 s 的位置只存一个 4 或 8 字节的地址值 - 真正字符串内容、“hello”这个字符数组、对象头等全部在堆中分配
- 该引用默认值是 null,不是 0 或空字符串
赋值和比较行为跟着存储方式走
因为栈里存的东西不同,操作结果自然不同。
- 基本类型赋值是值拷贝:修改副本不影响原变量
- 对象类型赋值是引用拷贝:两个变量指向同一块堆内存,改一个,另一个看到的也变
-
==对基本类型比数值是否相等;对对象类型比的是栈中两个地址是否相同(即是否指向同一个堆对象) - 要比较对象内容,得用
.equals(),且需确保该方法已被正确重写
为什么这样设计
根本原因是效率与灵活性的平衡。
- 基本类型小而固定,栈访问快,生命周期短,直接存值最省事
- 对象大小不可预知,可能很大或动态变化,堆能动态扩容,栈不适合承载
- 引用机制让多个变量可共享同一对象,节省内存,也支持多态和运行时绑定

















