中 基础
深拷贝与浅拷贝#
一句话答案#
浅拷贝只复制引用(指向同一对象),深拷贝递归复制所有引用对象,实现方式:序列化反序列化或手动递归复制。
核心要点
浅拷贝: Object.clone()默认 / BeanUtils.copyProperties 深拷贝: 序列化反序列化 / 手动递归 / JSON转换
面试回答(2分钟版)
浅拷贝和深拷贝的区别在于对引用类型字段的处理方式。浅拷贝只复制对象本身和基本类型字段的值,引用类型字段只复制引用地址,拷贝后的对象和原对象共享同一个引用对象——修改一个会影响另一个。Object.clone方法默认就是浅拷贝,Spring的BeanUtils.copyProperties也是浅拷贝。深拷贝则是递归复制所有引用对象,拷贝后完全独立互不影响。实现深拷贝有几种方式:最简单的是通过序列化反序列化,把对象序列化成字节流再反序列化出一个全新的对象,所有引用链都会被重新创建;也可以用JSON转换,先转JSON字符串再解析回对象;还可以手动递归实现每层clone。需要注意的是不可变对象如String和Integer不需要深拷贝,因为它们的值不会被修改,浅拷贝就足够安全。实际应用中缓存返回值、防御性复制等场景需要深拷贝来隔离修改,避免调用方意外篡改缓存中的数据。
追问与易错
追问方向:
- “BeanUtils.copyProperties 是深拷贝还是浅拷贝?”→ 浅拷贝,只复制属性值和引用地址,引用对象不会被递归复制,修改拷贝对象的引用属性会影响原对象
- “实现深拷贝的方式有哪些?”→ 序列化反序列化(对象流/Kryo)、JSON 转换(先 toJSON 再 parseObject)、手动递归复制、实现 Cloneable 并递归调用 clone
- “什么场景需要深拷贝?”→ 需要隔离修改的可变对象场景,如缓存返回值的防御性复制、多线程中传递可变对象、undo/redo 功能的状态快照
易错点:
- ❌ “实现 Cloneable 就是深拷贝”——Object.clone() 默认是浅拷贝
- ❌ 忽略不可变对象不需要深拷贝——String/Integer 等不可变对象浅拷贝即可