关于System.arraycopy浅拷贝的研究

前两天看java源码,看到ArrayList的add函数。

ArrayList中是用数组保存数据的,add函数如下:

1 public void add(int index, E element) {
2     rangeCheckForAdd(index); //教研index是否超出范围
3 
4     ensureCapacityInternal(size + 1);  // 由于要添加新元素,这里需要确保数组大小满足size+1
5     System.arraycopy(elementData, index, elementData, index + 1,
6                      size - index); //拷贝移位
7     elementData[index] = element; //将新元素放在指定位置
8     size++; //增加size
9 }

 

  这里我对这个System.arraycopy 比较感兴趣,因为这里是从一个数组拷贝到同一个数组,竟然不担心会出现拷贝错误的情况。

  下意识以为 System.arraycopy实现方式是这样:

public static native void arraycopy(Object src,  int  srcPos, 
                                   Object dest, int destPos, int length)
{
      for(int i=0;i<length;i++)
      {
       dest[destPos+i] = src[srcPos+i];
     }
 }

  如果这个函数按照上面这样设计,那么可能会出现错误

设原先数组为 
Integer[] array = {obj0, obj1, obj2, obj3},

若执行上面设计的代码,那么执行完 System.arrayCopy(array, 0, array, 1, 3);之后,
按照推断array的结果应该为
array == {obj0, obj0, obj0, obj0};

但是,事实上这个函数却没有出错:

java提供的System.arrayCopy函数却能正确的得到 {obj0, obj0, obj1, obj2}

  

带着好奇,查看System.arraycopy()函数注释,得到下面这段:

 * If the <code>src</code> and <code>dest</code> arguments refer to the
 * same array object, then the copying is performed as if the
 * components at positions <code>srcPos</code> through
 * <code>srcPos+length-1</code> were first copied to a temporary
 * array with <code>length</code> components and then the contents of
 * the temporary array were copied into positions
 * <code>destPos</code> through <code>destPos+length-1</code> of the
 * destination array.

 

意思就是,如果src与dest是同一个数组(设为array),那么这个函数执行起来就像是先把array的内容拷贝到一个相同大小的临时数组(设为tmp),
再将数据从tmp的srcPos~srcPos+length-1拷贝到array的destPos~destPos+length-1。

在拷贝过程,tmp保存了和原先数组相应的对象引用顺序,因此拷贝对象指针时才不会出现顺序错乱的情况。

  

 

posted @ 2018-11-07 20:53  Xinxin_Brian  阅读(224)  评论(0编辑  收藏  举报