java中基本类型存值于栈,引用类型变量存地址于栈、对象存于堆;赋值时基本类型拷贝值、引用类型拷贝地址;基本类型有默认值且不可为null,引用类型默认为null易致npe;==比较基本类型值、引用类型地址,内容比较须用equals()。

写 Java 程序时,搞不清基本类型和引用类型,就像开车不看油表——表面能跑,但容易抛锚、卡顿甚至突然崩溃。关键不是记多少概念,而是理解它们在内存里怎么存、赋值时怎么传、比较时怎么看,这些细节直接决定代码是否健壮。
内存位置与存储内容:栈里放什么,堆里放什么
基本类型变量(如 int、boolean、char)在栈中直接存值。比如 int count = 5;,栈里就实实在在放着数字 5;boolean flag = true;,栈里存的就是 true 这个逻辑状态。
引用类型变量(如 String、ArrayList、自定义类对象、数组)在栈里只存一个地址,真正的数据在堆里。比如 String name = "Tom";,栈中变量 name 存的是指向堆中 "Tom" 字符串对象的指针,字符串本身在堆上。
- 所有基本类型(8 种)都固定分配在栈中,无例外
- 引用类型变量本身在栈,它所指向的对象一定在堆——哪怕是一个
int[]数组,整个数组也是堆对象 - 栈内存线程私有、分配释放快;堆内存共享、需 GC 管理,这是性能差异的根源
赋值与参数传递:复制值还是复制地址
基本类型赋值是“拷贝一份值”,两个变量完全独立。修改其中一个,另一个毫发无伤。
引用类型赋值是“拷贝一份地址”,多个变量可能指向同一块堆内存。通过任一变量修改对象内容,其他变量立刻可见。
-
int a = 10; int b = a; b = 20;→ a 仍是 10 -
List<string> list1 = new ArrayList(); List<string> list2 = list1; list2.add("x");</string></string>→ list1 也会包含 "x" - 方法传参同理:基本类型传进去的是副本;引用类型传进去的是地址副本,仍指向原对象
默认值与空值处理:什么时候会出 NullPointerException
类成员变量有默认值:基本类型默认为 0 / false / '\u0000';引用类型统一为 null。局部变量则必须显式初始化,否则编译不通过。
正是这个 null,成为 NullPointerException 的主要来源。基本类型永远不可能为 null,所以用 int status 做状态码比用枚举对象更安全、更轻量。
- 声明
String s;(成员变量)→ s 默认为 null,直接调用s.length()抛 NPE - 声明
int x;(成员变量)→ x 默认为 0,可直接参与运算 - 局部变量如
String t;未赋值就使用 → 编译报错,提前拦截问题
比较方式与实际用途:== 到底在比什么
基本类型用 == 比较值是否相等,直观可靠。
引用类型用 == 比较的是地址是否相同,即是否为同一个对象;要判断内容是否一样,必须用 .equals()。
-
int a = 100, b = 100; a == b→ true(数值相等) -
String s1 = "abc"; String s2 = "abc"; s1 == s2→ 通常 true(字符串常量池复用) -
String s3 = new String("abc"); s1 == s3→ false(不同对象,地址不同),但s1.equals(s3)→ true - 包装类如
Integer在 -128~127 范围内缓存对象,超出后==不再可靠,一律用equals()或先拆箱
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











