补充--【Java全栈】 堆栈与创建对象结合的理解

📅 2026/7/13 14:32:53
补充--【Java全栈】 堆栈与创建对象结合的理解
1. 栈内存虚拟机栈 通俗理解就是厨房的临时操作台。每个方法被调用时都会分配一张独立的操作台专业名叫「栈帧」操作台上只放这个方法里的局部变量、参数这些小东西比如基本类型的值、对象的地址方法执行完操作台立刻撤走上面的东西自动清空速度非常快。2. 堆内存 通俗理解就是厨房的大仓库。所有真正的「对象本体」都存在这里比如一杯奶茶、一个用户对象体积大、占空间空间很大东西不会自动消失没人用的对象会由「垃圾回收器」相当于仓库清洁工定期清理掉每个对象在仓库里都有一个唯一的「货架编号」就是内存地址。 区别栈里放的是“小数据、临时数据”基本类型的值、对象的地址引用堆里放的是“完整的大对象”对象本体所有属性的真实值都存在这里。核心拆解一行new代码底层到底做了4件事我们拿这行最常见的代码举例拆成一步一步看每一步都讲清栈和堆分别发生了什么MilkTea tea new MilkTea(珍珠, 12);第1步遇到new→ 堆里先划出内存生成空白对象雏形JVM 先去堆内存大仓库里找一块空闲的位置按照MilkTea类的大小划出一块独立的内存空间生成一个空白的对象雏形。这一步做完的结果内存空间已经分配好了所有属性都会被自动赋予「默认零值」引用类型比如String taste默认是null空什么都没有数字类型比如double price默认是0.0布尔类型默认是false注意这时候还只是个“空壳”还不是一个能正常使用的完整对象此时还完全没调用构造方法。✅ 划重点分配内存、生成空白对象雏形是new指令独立完成的和构造方法无关。第2步调用构造方法 → 给空白对象做装配、初始化空白内存块生成后JVM 会立刻调用你写的构造方法把参数珍珠、12传进去执行构造方法里的赋值、校验等逻辑public MilkTea(String taste, double price) { this.taste taste; this.price price; }执行完之后堆里那个空白对象的属性就被覆盖成了你指定的值taste珍珠price12。✅ 构造方法的真实作用给已经分配好内存的空白对象做初始化、装配属性相当于“出厂灌装”把一个不能用的空壳变成一个真正可用的完整对象。第3步生成对象的唯一内存地址对象初始化完成后会得到它在仓库里的唯一「货架编号」也就是内存地址比如0xabc123这种格式。第4步把地址交给栈里的变量在当前方法的操作台栈内存上创建一个叫tea的变量把刚才的内存地址存进去。 最终状态栈里的tea变量存的是一串地址编号不是奶茶本身堆里的对象存着真实的口味、价格等所有数据是完整可用的tea就像取餐号拿着它就能找到堆里对应的对象。new关键字负责在堆内存分配空间、生成空白对象雏形构造方法负责把这个空白对象装配成真正可用的完整对象。二者分工不同有明确的先后顺序共同完成对象的完整创建。 生活化类比再强化new关键字 工厂的注塑机先吹出一个空白的奶茶杯外壳分配内存、赋默认零值构造方法 灌装工人往空杯子里加茶底、加奶、加珍珠初始化属性、装配完整变量tea 取餐号告诉你成品杯子放在仓库哪个位置你不能说“工人造出了杯子”也不能说“空杯子就是成品奶茶”——空杯是注塑机做的配料是工人装的二者合在一起才做出了一杯能喝的完整奶茶。两个最容易懵的误区误区1tea变量就是对象本身✅ 正解tea只是栈里的一个地址纸条取餐号真正的对象本体在堆仓库里。这也是为什么MilkTea tea2 tea;不会产生新对象——只是抄了一遍取餐号两个变量指向堆里同一个对象改一个另一个会跟着变和之前讲的「引用类型值传递」是同一个底层逻辑。误区2构造方法报错/没执行完对象也已经存在了✅ 正解如果构造方法执行过程中抛出异常这个只分配了内存、但未完成初始化的对象会被 JVM 回收掉最终并不会产生一个可用的对象。这也从侧面说明完整对象的创建是「分配内存 构造初始化」两个步骤共同完成的缺一不可。ps给昨天的创建对象做个补充