最近刚开始看java sdk的源码,看到ArrayList的toArray()的实现,如下:
/**
     * Returns an array containing all of the elements in this list
     * in proper sequence (from first to last element).
     *
     * <p>The returned array will be "safe" in that no references to it are
     * maintained by this list.  (In other words, this method must allocate
     * a new array).  The caller is thus free to modify the returned array.
     *
     * <p>This method acts as bridge between array-based and collection-based
     * APIs.
     *
     * @return an array containing all of the elements in this list in
     *         proper sequence
     */
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }
看到这句“The returned array will be "safe" in that no references to it are  maintained by this list.”,有点像是在说它是一个深复制。但是我又看到ArrayList的clone方法实现:
/**
     * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
     * elements themselves are not copied.)
     *
     * @return a clone of this <tt>ArrayList</tt> instance
     */
    public Object clone() {
        try {
            @SuppressWarnings("unchecked")
                ArrayList<E> v = (ArrayList<E>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError();
        }
    }
注释说clone方法返回的是浅复制。 为什么底层都是使用Arrays.copyOf进行复制,一个是浅复制一个是深复制呢?然后我写了段测试的代码:
public class Test {
public static void main(String[] args) {
ArrayList<A> list1=new ArrayList<A>();
list1.add(new A());
@SuppressWarnings("unchecked")
ArrayList<A> list2=(ArrayList<A>)list1.clone();
Object[] list3=list1.toArray();
list1.get(0).i=1;
System.out.println(list2.get(0).i);
System.out.println(((A)list3[0]).i);
}
}
class A{
public int i;
public A(){
i=0;
}
}
输出结果是 1   1.   很奇怪,toArray并没有像它说的那样是安全的啊。请各位前辈有知道的帮我解答一下,十分感谢!

解决方案 »

  1.   

    对于对象数组来说,Arrays.copyOf方法复制的是引用。
    按thinking in java里比喻的,引用是遥控器,真正的对象是电视,复制一个遥控器给你,操作的还是那个电视看下面的代码
    public class ListTest { public static void main(String[] args) {
    MyObject[] m1 = new MyObject[1];
    m1[0] = new MyObject();
    MyObject[] m2 = Arrays.copyOf(m1, 1);
    System.out.println(m1[0] == m2[0]);
    }
    }class MyObject {}输出true
      

  2.   

    谢回复!  
    The returned array will be "safe" in that no references to it are
         * maintained by this list.  (In other words, this method must allocate
         * a new array).  The caller is thus free to modify the returned array.
    为什么我觉得这段注释的意思是指Arrays.copyOf分配了一个新的array,然后我们操作这个返回的array并不会影响到源数组?