中?
" />
在 Java 中向 List 添加子列表时,必须添加新副本而非原始引用,否则后续修改会影响已存入的结果列表,导致所有元素变为空列表。
在 java 中向 list> 添加子列表时,必须添加新副本而非原始引用,否则后续修改会影响已存入的结果列表,导致所有元素变为空列表。
当调用 res.add(list) 时,实际是将同一个 list 对象的引用多次加入外层列表。随着回溯执行 list.remove(list.size() - 1),该对象内容持续被修改,最终所有已添加的引用都指向一个已被清空的列表。
✅ 正确做法是创建独立副本:
res.add(new ArrayList(list)); // 深拷贝当前状态
new ArrayList(list) 调用构造器,遍历原列表并逐个添加元素,生成一个全新、独立、内容相同但地址不同的 ArrayList 实例。这样每个存入 res 的子列表都固化了递归到达叶子节点时的路径快照。
⚠️ 注意事项:
- List
- > res = new ArrayList(); 是推荐写法(利用类型推断),等价于 new ArrayList
- >(),二者均合法;
- List 是接口,ArrayList 是其实现类;声明用 List(面向接口编程),实例化用 ArrayList(具体实现);
- 单纯 res.add(list) 不会编译报错,但逻辑错误隐蔽,需结合回溯生命周期理解引用语义;
- 若 list 内含自定义对象,且需深层复制(如对象属性也被修改),则 new ArrayList(list) 仅是浅拷贝,此时需手动克隆或使用序列化等方案。
总结:在回溯或状态暂存场景中,向嵌套集合添加“当前状态”时,务必通过构造器或 List.copyOf()(Java 10+)创建不可变/独立副本,避免共享可变状态引发的数据污染。










