clone(): ArrayList.clone() I thought does a shallow copy

后端 未结 6 1792
别那么骄傲
别那么骄傲 2020-11-29 05:59
ArrayList a=new ArrayList();
a.add(5);
ArrayList b=(ArrayList)a.clone();
a.add(6);
System.out.println(b.t         


        
6条回答
  •  自闭症患者
    2020-11-29 06:25

    This indeed does a shallow copy, here is a comment for clone, from ArrayList source code

    Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.)

    To understand this, let's look at a snippet in clone method from ArrayList

    v.elementData = Arrays.copyOf(elementData, size);
    

    As we know, when we assign an Object to a variable, JAVA does not make a brand new copy of that Object. Instead, this variable becomes another reference pointing to the original Object.

    Thus, elementData are actually storing reference to objects put into this ArrayList. And clone just copy these references, no replicas of Objects are created.

    Of course, you can remove or add new reference to a cloned ArrayList.

    However, modification of old Objects in one ArrayList will effect the original ArrayList. It's hard to do illustration with your example since Integer is immutable.

    To see the side effect, you can define a custom mutable Object

    class Person {
            private int a;
    
            public void setA(int a) {
                this.a = a;
            }
            public int getA() {
                return a;
            }
            @Override
            public String toString() {
                return String.valueOf(a);
            } 
       } 
    

    Then you can use the following code to make test

            Person p1 = new Person();
            Person p2 = new Person();
    
            ArrayList tt = new ArrayList();
            tt.add(p1);
            tt.add(p2);
    
            ArrayList yy = (ArrayList) tt.clone();
            Person vv = yy.get(yy.indexOf(p2));
            vv.setA(12);
            yy.remove(p1);
    
            System.out.println("tt: " + tt);
            System.out.println("yy: " +yy);
    

    The output should be

    tt: [0, 12]
    yy: [12]

    See the side effect :) ? We only change the element in yy, but it is also reflected in tt.

提交回复
热议问题