程序员 · 高频练习

复制对象后修改嵌套列表,为什么原对象也跟着变化?

初级 单选题 第 959 题 中等 程序员浅拷贝深拷贝对象引用可变对象
题目

对象 order 内含一个可变列表 items。程序对 order 做浅拷贝得到 backup,随后向 backup.items 中添加商品,结果 order.items 也出现了同一商品。最合理的解释是()。

A 浅拷贝生成了新的外层对象,但内部items仍与原对象引用同一个列表
B 任何复制操作都会让两个变量始终指向同一个外层对象
C 列表只能读取,不能被修改
D CPU缓存自动把两个无关列表合并了
题目类型:原创高频练习题 用途:用于帮助理解程序员相关考点和答案解析,不等同于官方真题。
正确答案
A
答案解析

浅拷贝通常复制外层容器,但其中的引用成员仍指向原来的可变对象。因此修改共享的 items 列表会同时从 order 和 backup 观察到;深拷贝才会进一步复制嵌套可变对象。

选项分析

A

正确。外层对象已分开,嵌套列表引用仍共享,修改列表内容会互相可见。

B

错误。浅拷贝通常会创建新的外层对象,并非两个变量始终指向同一外层实例。

C

错误。题干明确列表可变,追加操作能够发生。

D

错误。对象引用共享由程序语义造成,与CPU缓存合并对象无关。

本题为什么容易错

有人记成“浅拷贝等于没拷贝”。这不准确:外层通常已经是新对象,只是内部引用的对象未递归复制。

先看结论

简短答案

复制对象后修改嵌套列表,为什么原对象也跟着变化,正确答案是 A(浅拷贝生成了新的外层对象,但内部items仍与原对象引用同一个列表)。浅拷贝通常复制外层容器,但其中的引用成员仍指向原来的可变对象。因此修改共享的 items 列表会同时从 order 和 backup 观察到;深拷贝才会进一步复制嵌套可变对象。

解析

易混淆概念对比表

概念本题判断区别要点记忆提示
浅拷贝生成了新的外层对象,但内部items仍与原对象引用同一个列表 本题正确答案 正确。外层对象已分开,嵌套列表引用仍共享,修改列表内容会互相可见。 看到题干核心场景时优先联想到它
任何复制操作都会让两个变量始终指向同一个外层对象 本题干扰项 错误。浅拷贝通常会创建新的外层对象,并非两个变量始终指向同一外层实例。 看到该词不要急着选,先判断是否真正解决题干问题
列表只能读取,不能被修改 本题干扰项 错误。题干明确列表可变,追加操作能够发生。 看到该词不要急着选,先判断是否真正解决题干问题
CPU缓存自动把两个无关列表合并了 本题干扰项 错误。对象引用共享由程序语义造成,与CPU缓存合并对象无关。 看到该词不要急着选,先判断是否真正解决题干问题
本题易混淆选项怎么区分
  • 任何复制操作都会让两个变量始终指向同一个外层对象:错误。浅拷贝通常会创建新的外层对象,并非两个变量始终指向同一外层实例。
  • 列表只能读取,不能被修改:错误。题干明确列表可变,追加操作能够发生。
  • CPU缓存自动把两个无关列表合并了:错误。对象引用共享由程序语义造成,与CPU缓存合并对象无关。
复习

知识点详解

浅拷贝创建新的外层对象,并复制其成员值;若成员值是对象引用,复制的仍是引用,所以两个外层对象可能共享内部可变对象。深拷贝会递归复制对象图,使对应可变成员相互独立,但需处理循环引用、不可复制资源、性能成本和业务身份语义。实际代码不应默认越深越好,而应明确哪些状态需要共享、哪些状态需要隔离。

备考速记

浅拷贝换外壳,里面的引用可能共用;深拷贝再复制需要隔离的内层。

可变对象在可变对象场景中的作用

可变对象在本题中的核心价值,是解决“对象 order 内含一个可变列表 items。程序对 order 做浅拷贝得到 backup,随后向 backup.items 中添加商品,结果 order.items 也出现了同一商品。最合理的解释是()”这个场景问题。复习时不要只背选项名称,还要理解它为什么适用于该场景,以及它能解决哪类安全、流程或管理问题。

拓展

同类题怎么考

  • 根据嵌套对象修改结果判断浅拷贝。
  • 选择需要独立快照时的复制策略。
可变对象在程序员软考中的考法

软考选择题通常不会只考概念定义,还会把可变对象放到可变对象场景中,要求判断它的作用、适用范围或与相近概念的区别。遇到这类题时,先抓住题干中的业务场景,再看哪个选项最能解决该场景下的核心问题。

解题思路

可以把外层对象想成两个新文件夹,items 是文件夹里的一张地址卡。浅拷贝复制了文件夹和地址卡内容,但地址卡仍写着同一个列表地址。你通过 backup 找到列表并追加商品,order 再沿原地址看过去,当然也能看到。选 A。若业务要求备份完全独立,还要考虑深拷贝或显式复制需要隔离的成员。

考点定位

先区分修改外层字段还是修改共享的嵌套对象。浅拷贝后替换 backup.items 与向 backup.items 追加元素,结果可能不同。

易错提醒

  • 对含文件句柄、锁或数据库连接的对象盲目深拷贝。
  • 以为所有不可变成员也必须递归复制才能安全。
  • 复制后只测试外层字段,没有测试嵌套集合的修改。

备考提示

  • 画两个外层框,再用箭头连接同一个items列表,理解浅拷贝。
  • 分别测试替换列表引用和修改列表内容,观察原对象变化。

你可能还想了解

  • 浅拷贝是否会创建新对象?
  • 为什么替换列表与修改列表内容结果不同?
  • 深拷贝为什么不适合所有对象?

本文小结

浅拷贝会创建新的外层对象,但嵌套可变对象可能仍共享同一引用。因此修改backup.items的内容时,原对象order.items也会观察到变化。