java中基本类型存值于栈,引用类型存地址于栈、对象于堆;基本类型赋值拷贝值、==比数值,引用类型赋值拷贝地址、==比地址;基本类型不可为null且有默认值,引用类型可为null。

Java中引用类型和基本类型在内存分配上的差异,核心在于“存什么”和“存在哪”两件事——基本类型直接存值,在栈里搞定;引用类型只存地址,真东西全在堆里。
基本类型:值在栈中,独立又固定
8种基本类型(byte、short、int、long、float、double、char、boolean)声明时,JVM直接在栈中分配一块固定大小的空间,把数值原样放进去。比如 int age = 25,栈里就实实在在存着数字25。
- 每个类型占用空间确定:int占4字节,char占2字节,boolean虽逻辑上1位,但实际按1字节对齐
- 变量生命周期绑定作用域:方法执行完,对应栈帧弹出,值自动消失
- 未初始化也有默认值:int为0,boolean为false,不会出现null
引用类型:栈中存地址,堆中存对象
类、接口、数组、枚举、注解等都属于引用类型。声明如 String name = "Alice" 或 ArrayList list = new ArrayList() 时,栈中只存一个地址,真正的对象数据(比如字符串内容、数组元素、对象字段)全在堆中动态创建。
- 栈中变量是轻量级的“路标”,不包含实际数据
- 堆中对象由GC管理:栈里引用没了,对象不一定立刻销毁,得等垃圾回收器判定其不可达
- 数组也是引用类型:哪怕
int[] nums = {1,2,3},变量nums本身在栈中存地址,整个数组对象(含3个int元素)都在堆里
赋值与比较行为直接受内存布局影响
内存怎么放,决定了代码怎么跑。
- 基本类型赋值是值拷贝:
int a = 10; int b = a;→ b得到的是10的副本,改b不影响a - 引用类型赋值是地址拷贝:
StringBuilder s1 = new StringBuilder("a"); StringBuilder s2 = s1;→ s1和s2指向堆中同一个对象,调用s2.append("b")后,s1.toString()也变成"ab" -
==比较含义不同:基本类型比数值是否相等;引用类型比地址是否相同(即是否指向同一块堆内存)
null 和默认值体现根本差异
基本类型不能为null,因为它们必须有确定的值;引用类型天然支持null,正因为它只是个“可能为空的地址”。
-
int x;编译期就给默认值0;String s;默认值是null - 包装类(如Integer)是引用类型,所以
Integer i = null;合法,但int j = null;编译报错 - 缓存机制(如Integer[-128,127])是特例,不改变其作为引用类型的本质
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











