• 关于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保存了和原先数组相应的对象引用顺序,因此拷贝对象指针时才不会出现顺序错乱的情况。

      

  • 相关阅读:
    第十三篇:一点一滴学ibatis(二)映射文件
    第十二篇:随手记一下javaBean的setter,getter方法的命名问题
    第十一篇:一点一滴学ibatis(一)
    第十篇:javaScript中的JSON总结
    第九篇:Spring的applicationContext.xml配置总结
    第八篇:ZTree操作总结
    第六篇:fastJson常用方法总结
    第五篇:zTree节点的一些操作,权当备份
    第四篇:java读取Excel简单模板
    测试驱动android
  • 原文地址:https://www.cnblogs.com/xinxinBlog/p/9925611.html
Copyright © 2020-2023  润新知