Java中ArrayList的clone()方法与直接赋值操作是否等价?
结论:对ArrayList使用clone()方法和直接执行ArrayList v2 = v赋值,完全不是同一种操作。
两种操作的核心差异:
直接赋值
ArrayList v2 = v
该操作仅复制了集合对象的内存引用,v和v2指向堆中同一个ArrayList实例,二者只是同一个集合对象的两个别名。你对v2做任何集合结构修改(比如add()、remove()、clear()),都会同步反映到v上。clone()方法
ArrayList的clone()是浅拷贝实现,执行后会在堆中创建一个全新的独立的ArrayList实例,新集合本身和原集合互不干扰:你对v2做新增、删除元素等结构修改,完全不会影响原集合v。
但浅拷贝仅复制集合结构,不会复制集合中存储的元素对象,新集合和原集合存储的是同一批元素的引用。如果元素是可变对象,修改元素自身的属性时,两个集合读取到的元素属性会同步变化。
为什么你的示例输出完全一致?
你的两次测试中,所有操作都仅修改了集合内部存储的
Int对象的自身属性,没有修改集合本身的结构,刚好没有触发两种操作的差异点,并不是因为二者效果相同。
你可以通过以下代码验证二者的本质差异:
import java.util.*; public class TestCloneDiff { public static void main(String[] args) { ArrayList<Integer> v = new ArrayList<>(); v.add(1); v.add(2); // 测试clone场景 ArrayList<Integer> vClone = (ArrayList<Integer>) v.clone(); vClone.add(3); System.out.println("clone场景原集合v长度:" + v.size()); // 输出2,不受克隆集合新增操作影响 System.out.println("clone场景克隆集合vClone长度:" + vClone.size()); // 输出3 // 测试直接赋值场景 ArrayList<Integer> vAssign = v; vAssign.add(4); System.out.println("直接赋值场景原集合v长度:" + v.size()); // 输出3,和赋值后的集合同步变化 System.out.println("直接赋值场景赋值集合vAssign长度:" + vAssign.size()); // 输出3 } }
内容的提问来源于stack exchange,提问作者fabio palladino
相关产品推荐
相关产品推荐

