java.lang.System.arraycopy() 与java.util.Arrays.copyOf()的区别

一、java.lang.System.arraycopy()

该方法的声明:

  1. /* @param src 源数组
  2. * @param srcPos 源数组中的起始位置
  3. * @param dest 目标数组
  4. * @param destPos 目标数组中的起始位置
  5. * @param length 需要被复制的元素个数
  6. * @exception IndexOutOfBoundsException 如果在复制的过程中发生索引溢界异常
  7. * @exception ArrayStoreException 如果源数组中的元素因为类型不匹配不能被复制到目标数组中
  8. * @exception NullPointerException 如果源数组为null或者目标数组为null
  9. */
  10. public static native void arraycopy(Object src, int srcPos,
  11. Object dest, int destPos,
  12. int length); //由修饰符native可知,该方法调用的为JDK中的底层函数

该方法实现的功能为:从指定源数组中指定的位置开始,依次将元素复制到目标数组的指定位置,复制的元素个数为length参数。即,

          将数组src[srcPos, ..., srcPos+length-1]中的元素复制到数组dest[destPos, ..., destPos+length-1]中。

如果源数组(src)和目标数组(dest)为相同的数组对象,则复制过程为:

  ① 将源数组中需复制的元素src[srcPos, ..., srcPos+length-1]复制到一个临时数组中,长度为length;

  ② 然后将临时数组中的内容复制到目标数组dest[destPos, ..., destPos+length-1]中。

二、java.util.Arrays.copyOf()

该方法的声明:

  1. /* @param <T>      数组中元素的类型
  2. * @param original   被复制数组
  3. * @param newLength 返回的数组的长度
  4. * @return 返回源数组的一个“副本”,为了去达到指定的长度,必要情况下需截断或用null值填充
  5. * @throws NegativeArraySizeException 如果参数newLength为负值
  6. * @throws NullPointerException 如果参数original为null
  7. * @since 1.6
  8. */
  9. @SuppressWarnings("unchecked")
  10. public static <T> T[] copyOf(T[] original, int newLength) {
  11. return (T[]) copyOf(original, newLength, original.getClass());
  12. }
  13.  
  14. /* @param <U>   源数组中元素的类型
  15. * @param <T>   返回数组中元素的类型
  16. * @param original     被复制数组
  17. * @param newLength     返回的数组的长度
  18. * @param newType      返回数组的类型
  19. * @return     返回源数组的一个“副本”,为了去达到指定的长度,必要情况下需截断或用null值填充
  20. * @throws NegativeArraySizeException    如果参数newLength为负值
  21. * @throws NullPointerException       如果参数original为null
  22. * @throws ArrayStoreException       如果源数组中的元素不能被复制到类型为newType的数组中
  23. * @since 1.6
  24. */
  25. public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
  26. @SuppressWarnings("unchecked")
  27. T[] copy = ((Object)newType == (Object)Object[].class) //内部新建的返回数组
  28. ? (T[]) new Object[newLength] //(返回数组)的类型为Object[]时
  29. : (T[]) Array.newInstance(newType.getComponentType(), newLength); //用newType的组件类型,长度newLength去创建一个新的数组
  30. System.arraycopy(original, 0, copy, 0,
  31. Math.min(original.length, newLength)); //截断或用null值填充
  32. return copy;
  33. }
  34.   
      //java.util.Arrays重载了很多copyOf()方法
  35. public static int[] copyOf(int[] original, int newLength) {
  36. int[] copy = new int[newLength];
  37. System.arraycopy(original, 0, copy, 0,
  38. Math.min(original.length, newLength));
  39. return copy;
  40. }

该方法实现的功能为:按指定的长度复制给定的源数组,必要情况下需截断或用null值填充。 

Arrays.copyOf()的实现方式是:

  ① 内部新建一个长度为指定长度参数newLength的数组copy[];

  ② 调用System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength))完成对数组复制的功能

    if(original.length >= newLength)  截断original[];original[0, ..., newLength-1] -> copy[0, ..., newLength-1]

    if(original.length < newLength)  用null值填充;original[0, ..., original.length-1] -> copy[0, ..., original.length-1]

                             nulls -> copy[original.length, ..., newLength-original.length+1]

  ③ 返回一个长度为newLength的数组copy[],元素为②中得到的对应值

三、异同

1) Arrays.copyOf()内部是通过System.arraycopy()实现的。

2) System.arraycopy()通过对srcPos,destPos的设置完成对数组的任意部分复制功能;而Arrays.copyOf()只能从下标为0的元素开始复制。

3)System.arraycopy()中会因为srcPos+length > src.length 或 destPos+length > dest.length而报ArrayIndexOutOfBoundsException;而Arrays.copyOf()中不会因此而报错,因为Arrays.copyOf()返回的为方法内部新建的一个指定长度的数组。

  1. String[] a = {"a","b","c","d","e"};
  2. String[] b = new String[4];
  3. //System.arraycopy(a, 0, b, 0, ); //java.lang.ArrayIndexOutOfBoundsException
  4. //b = Arrays.copyOf(a, 4);        //截断a[],b={"a","b","c","d"}
  5. b = Arrays.copyOf(a, 5);        //b={"a","b","c","d","e"}
  6. //b = Arrays.copyOf(a, 6);        //null值填充,b={"a","b","c","d","e",null}

4) 在System.arraycopy()方法中,如果目标数组dest==null,则会报NullPointerException;而Arrays.copyOf()中不会因此而报错。

  1. String[] a = {"a","b","c","d","e"};
  2. String[] b = null;
  3. //System.arraycopy(a, 0, b, 0, 5);     //java.lang.NullPointerException
  4. b = Arrays.copyOf(a, 5);        //b={"a","b","c","d","e"}

5)System.arraycopy()方法中目标数组作为参数;而Arrays.copyOf()中目标数组作为返回值。

6) System.arraycopy()方法和Arrays.copyOf()方法均可以实现数组类型的向上转换,即子类型的数组可以复制到父类型数组中;但不可以实现向下转换,即父类型的数组不可以复制到子类型数组中。

  1. class A {}
  2. class B extends A{}
  3.  
  4. A a1 = new A();
  5. A[] parent = {a1,a1,a1,a1,a1};
  6. B[] child = new B[5];
  7. //child = (B[]) Arrays.copyOf(parent, 5);     //java.lang.ClassCastException
  8. //System.arraycopy(parent, 0, child, 0, 5);   //java.lang.ArrayStoreException
  9.  
  10. B b1 = new B();
  11. B[] child = {b1,b1,b1,b1,b1};
  12. A[] parent = new A[5];
  13. //parent = Arrays.copyOf(child,5);        //复制成功
  14. //System.arraycopy(child, 0, parent, 0, 5);   //复制成功

java.lang.System.arraycopy() 与java.util.Arrays.copyOf()的区别的更多相关文章

  1. Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V

    最近下载一个新版本的adt-bundle,Android API是20. 把Plain Text控件往布局上面拖时,发现拖不上去,出现了下面的错误: Exception raised during r ...

  2. ECLIPSE android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V

    在布局添加控件手动添加还是拖的添加,添加edittext后布局就不好用,其他控件好用,然后就说下面这段话 Exception raised during rendering: java.lang.Sy ...

  3. android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V

    今天在看布局文件的时候出现 android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[ ...

  4. 解决 Xamarin 拖拽Plain Text 于Layout上时 出现 “The layout could not be loaded:java.lang.System.arraycopy([CI[CII)V” 错误

    右键项目属性

  5. java.util.Arrays,java.lang.Math,java.lang.System 类的常用方法汇总

    java.util.Arrays类是数组的工具类,一般数组常用的方法包括 二分查找:public static int  binarySearch(array[],int key),返回key的下标i ...

  6. java的system.arraycopy()方法

    java.lang.System的静态方法arraycopy()可以实现数组的复制,讲课的老师说这个方法效率比较高,如果数组有成千上万个元素,那么用这个方法,比用for语句循环快不少.于是我试了试,发 ...

  7. java.lang.system 类源码解读

    通过每块代码进行源码解读,并发现源码使用的技术栈,扩展视野. registerNatives 方法解读 /* register the natives via the static initializ ...

  8. JavaSE-基础语法(二)-系统类(java.lang.*)和工具类(java.util.*)

    系统类(java.lang.*)和工具类(java.util.*) 一.系统类(java.lang.*) 这个包下包含java语言的核心类,如String.Math.System和Thread类等,使 ...

  9. Spring MVC exception - Invoking request method resulted in exception : public static native long java.lang.System.currentTimeMillis()

    最近在线上系统发现下面的异常信息: 2014-10-11 11:14:09 ERROR [org.springframework.web.servlet.mvc.annotation.Annotati ...

随机推荐

  1. 【大数据应用技术】作业八|爬虫综合大作业Molly134

    本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075 前言:本次作业是爬取CBO中国票房2010-2019年每年 ...

  2. MongoDB中的数据导出为excel CSV 文件

    1.打开命令行,进入我们所安装的mongodb路径下的bin文件夹 2.我们采用bin文件夹下的mongoexport方法进行导出, mongoexport -d myDB -c user -f _i ...

  3. 个人阅读&个人总结

    个人阅读作业+总结 助教推荐的那些文章都是软件工程上的经典文章,阅读后感受到软件工程本身的深度,之前学习的软件工程都只是皮毛之中的皮毛而已.随着软件规模的越来越庞大,软件工程已经成为了软件开发中的必备 ...

  4. 『编程题全队』Alpha 阶段冲刺博客集合

    『编程题全队』Alpha 阶段冲刺博客集合 »Day1 2018年4月19日 博客连接:『编程题全队』Alpha 阶段冲刺博客Day1 »Day2 2018年4月20日 博客连接:『编程题全队』Alp ...

  5. python基础(三)python数据类型

    一.数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需 ...

  6. Redis&PHP的使用安装-windows版

    Redis是一个Key-value的数据结构存储系统,可以以数据库的形式,缓存系统,消息处理器使用,它支持的存储value类型很多,例如,string.list(链表).set(集合).zset(so ...

  7. c++ 替换修改一个文件夹下的所有文件的文件名

    代码简洁,亲测可用. 1,首先来获取(输出)一个文件夹中所有的文件名 void getFiles(string path, vector<string>& files) { //文 ...

  8. 12:打印1到最大的n位数

    面试题12:打印1到最大的n位数 剑指offer题目12,题目如下 输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的三位数999 方法一 和面试题11< ...

  9. List<Map> 进行求和

    public class Main { public static void main(String[] args) { List<Map> lists = new ArrayList&l ...

  10. BeanCopier

    cglib是一款比较底层的操作java字节码的框架. 下面通过拷贝bean对象来测试BeanCopier的特性: public class OrderEntity { private int id; ...