java集合存储的是对象引用而非副本,导致共享修改、null需判空、强引用阻碍gc等关键行为。

Java 集合中实际存储的不是对象本身,而是对象的引用(即内存地址),这一点对理解集合行为、内存管理及常见陷阱至关重要。
集合里存的是“指向对象的指针”,不是对象副本
Java 中所有非基本类型(如 String、ArrayList、自定义类实例)在集合中都以引用形式存储。比如:
-
List
list = new ArrayList(); —— 实际存入的是字符串常量池中 "hello" 对象的引用,不是复制一份新字符串;
list.add("hello"); - list.add(new Person("Alice")); —— 存的是堆中 Person 实例的引用,多个集合元素可指向同一个对象;
- 修改集合外的原对象(如 person.setName("Bob")),若该 person 已被 add 进集合,集合里看到的就是更新后的状态。
引用传递导致的“共享对象”问题
因为存的是引用,多个集合或变量可能指向同一对象,容易引发意外修改:
- 把同一个 ArrayList 实例先后 add 到两个 List 中,修改其中一个内部元素,另一个也会“感知”到变化;
- 遍历集合时直接修改元素对象的属性(如 list.get(i).setAge(25)),影响的是原始对象;
- 若需独立副本,应显式克隆(实现 Cloneable)或构造新对象(new Person(p.getName(), p.getAge()))。
null 引用也是合法的存储值
除某些严格集合(如 ConcurrentHashMap 不允许 null key/value),多数集合(ArrayList、LinkedList、HashSet)允许存 null 引用:
- list.add(null); 是合法操作,get() 返回 null,但调用其方法会触发 NullPointerException;
- 判断元素是否存在时,contains(null) 在支持 null 的集合中返回 true;
- 使用前务必检查是否为 null,尤其在 forEach 或 stream 操作中。
弱引用、软引用与集合的特殊配合
标准集合(HashMap、ArrayList 等)使用强引用,会阻止 GC 回收。若需自动清理,可搭配引用队列与特殊集合:
- WeakHashMap:key 是弱引用,当 key 无其他强引用时,对应 entry 可被自动移除;
- ReferenceQueue + PhantomReference 可用于监听对象回收,配合自定义缓存清理逻辑;
- 避免直接用 WeakReference
[] 手动管理,推荐使用 java.util.concurrent 包中已封装好的工具类。
不复杂但容易忽略:集合操作的本质是引用操作,理解这点,就能避开大部分“对象莫名改变”“内存泄漏”和“空指针”的坑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











