System.arraycopy方法的简短总结

API使用场景

在JDK研发团队的开发过程当中,对集合的操做过程当中常会使用到此方法。c++

API参数

public static native void arraycopy(
       Object src,  //源数组
       int srcPos,  //源数组的读取起始位置
       Object dest, //目标数组
       int destPos, //目标数据中的写入起始位置
       int length   //要复制的数组元素的数量
       );

Functions

  1. 将指定源数组的数组从指定位置复制到目标数组的指定位置。数组组件的子序列由src引用的源数组复制到dest引用的目标数组。复制的组件数等于length。源序列中从srcPos到srcPos+length-1的序列复制到目标序列的destPos到destPos+length-1位置。
  2. 若是src和dest参数引用的是相同的数组对象,则首先把源数组srcPos到srcPos+length-1的组件复制到具备与此相同长度的临时数组里,而后再把临时数组的内容复制到目标数组destPos到destPos+length-1位置。
  3. 若是dest为null,则抛出NullPointerException;若是src为空,则抛出NullPointerException,而且不修改目标数组。
  4. 抛出ArrayStoreException的状况(前7种状况不会修改dest):
    1)src参数指向的不是数组对象
    2)dest参数指向的不是数组对象
    3)src参数和dest参数指向的对象类型不是同一种基本类型的数组
    4)src参数指向由原始组件类型组成的数组,dest参数指向由引用组件类型组成的数组
    5)dest参数指向由原始组件类型组成的数组,src参数指向由引用组件类型组成的数组
    6)srcPos+length>src.length
    7)destPos+length>dest.length
    8)对于任意i知足:srcPos <= i <= (srcPos+length-1),src.get(i)没法转换为dest的成员类型。(这种状况下,令k为小于length的非负整数,假设此时使src[srcPos+k]不能转换为目标数组的成员类型,当抛异常时srcPos到srcPos+k-1的源数组成员已经经过destPos+k-1被复制到目标数组的destPos位置,目标数组的剩余位置不会被修改。这种状况仅适用于两个数组都具备引用类型的成员类型的状况)

方法特性

一、总的来讲,复制方式属于浅复制数组

  • 复制的过程只是引用变量的二次传递。
  • 一维数组的复制:属性值传递,修改则不会影响副本
  • 二维数组的复制:复制的是第一维的引用列表,副本和原数组的指向是相同的堆地址,这个时候,值变更的影响是双向的

二、此方法不是线程安全的,必要时要加锁限制。
三、相比for遍历复制,此方法更加高效。安全

  • 缘由很简单,该方法使用内存块总体读取与复制,相比for的遍历寻址来讲天然会快,不过这个速度优点在数组成员比较多的时候才会有较明显的体现。下面贴出native方法中关键部分copy的方法c++代码:
void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
    if (from > to) {
      jint *end = from + count;
      while (from < end)
        *(to++) = *(from++);
    }
    else if (from < to) {
      jint *end = from;
      from += count - 1;
      to   += count - 1;
      while (from >= end)
        *(to--) = *(from--);
    }
}
相关文章
相关标签/搜索