java中引用类型变量的存取本质是地址传递而非对象搬运,通过aload系列指令将引用从局部变量表加载到操作数栈顶,astore系列指令将栈顶引用存回局部变量表,new对象时需dup复制地址以兼顾构造与赋值。

Java中引用类型变量的存取,本质是操作局部变量表与操作数栈之间的地址传递,不是对象本身搬运。
引用变量入栈用 aload 指令
当方法需要使用某个引用变量(比如 String s 或 List list)时,JVM 通过 aload 系列指令把它从局部变量表“搬”到操作数栈顶,供后续调用、比较或传参使用。
- aload_0:加载局部变量表索引 0 处的引用(通常是 this)
- aload_1:加载索引 1 处的引用(常为第一个形参)
- aload n:加载任意索引 n 的引用(n > 3 时使用,带显式操作数)
引用变量出栈存入局部变量用 astore 指令
创建对象或方法返回引用后,需把操作数栈顶的引用地址写回局部变量表——这由 astore 系列指令完成。
- astore_0:将栈顶引用存入索引 0
- astore_1:存入索引 1(如 astore_1 常见于 new Object() 后赋值给形参或局部变量)
- astore n:存入任意索引 n 的位置
new 对象时的典型字节码流程含两次 astore
以 Object o = new Object(); 为例,关键步骤包括:
- new #2:在堆中分配内存,对象地址压栈
- dup:复制该地址,栈中出现两个相同引用
-
invokespecial #3:用一个地址调用
,构造完成后该地址出栈 - astore_1:将剩余的那个地址存入局部变量表索引 1(即变量 o)
注意:aload/astore 操作的是“引用值”,不是对象内容
这些指令只处理 32 位(或 64 位,取决于 JVM 模式)的对象地址。即使你修改了 list.add("x"),astore_1 也不会重执行——因为变量里存的仍是同一个地址。所谓“修改对象”,实际是通过该地址访问堆上数据并变更其字段,和局部变量表无关。
换句话说:引用传递的本质,在字节码层就是地址值的复制与搬运;而所有 aload / astore 指令,只是在管理这个地址值在栈帧中的流动路径。











