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

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

一、java.lang.System.arraycopy()

该方法的声明:

    /* @param      src      源数组
     * @param      srcPos   源数组中的起始位置
     * @param      dest     目标数组
     * @param      destPos  目标数组中的起始位置
     * @param      length   需要被复制的元素个数
     * @exception  IndexOutOfBoundsException  如果在复制的过程中发生索引溢界异常
     * @exception  ArrayStoreException  如果源数组中的元素因为类型不匹配不能被复制到目标数组中
     * @exception  NullPointerException 如果源数组为null或者目标数组为null
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        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()

该方法的声明:

    /* @param <T>      数组中元素的类型
     * @param original   被复制数组
     * @param newLength    返回的数组的长度
     * @return   返回源数组的一个“副本”,为了去达到指定的长度,必要情况下需截断或用null值填充
     * @throws NegativeArraySizeException  如果参数newLength为负值
     * @throws NullPointerException        如果参数original为null
     * @since 1.6
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

    /* @param <U>   源数组中元素的类型
     * @param <T>   返回数组中元素的类型
     * @param original     被复制数组
     * @param newLength     返回的数组的长度
     * @param newType      返回数组的类型
     * @return     返回源数组的一个“副本”,为了去达到指定的长度,必要情况下需截断或用null值填充
     * @throws NegativeArraySizeException    如果参数newLength为负值
     * @throws NullPointerException       如果参数original为null
     * @throws ArrayStoreException        如果源数组中的元素不能被复制到类型为newType的数组中
     * @since 1.6
     */
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)  //内部新建的返回数组
            ? (T[]) new Object[newLength]    //(返回数组)的类型为Object[]时
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);  //用newType的组件类型,长度newLength去创建一个新的数组
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength)); //截断或用null值填充
        return copy;
    }
    //java.util.Arrays重载了很多copyOf()方法
    public static int[] copyOf(int[] original, int newLength) {
        int[] copy = new int[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

该方法实现的功能为:按指定的长度复制给定的源数组,必要情况下需截断或用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()返回的为方法内部新建的一个指定长度的数组。

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

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

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

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

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

class A {}
class B extends A{}

A a1 = new A();
A[] parent = {a1,a1,a1,a1,a1};
B[] child = new B[5];
//child = (B[]) Arrays.copyOf(parent, 5);      //java.lang.ClassCastException
//System.arraycopy(parent, 0, child, 0, 5);    //java.lang.ArrayStoreException

B b1 = new B();
B[] child = {b1,b1,b1,b1,b1};
A[] parent = new A[5];
//parent = Arrays.copyOf(child,5);         //复制成功
//System.arraycopy(child, 0, parent, 0, 5);   //复制成功
时间: 2024-08-24 01:37:16

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

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

今天在看布局文件的时候出现 android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V 提醒,google后在网上说是因为sdk版本的问题. 解决方法: 修改选择不同的API就好了,降低版本即可

How to solve Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V in Android

android开发打开别人的项目的时候,手机面板上的控件有时候不能显示,还显示错误信息: Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V Exception details are logged in Window > Show View > Error Log 原因是目前采用的API版本与原来的API版本不匹配,把API版本改一下即可.

Android的布局文件遇到Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V问题

打开xml的布局文件,发现布局无法显示预览,而且报错:Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V.原来是因为用了最新的API 20.这个是Android用于开发可穿戴设备的,不支持EditText.将API改为20之前的就行了.

Android - Exception raised during rendering: java.lang.System.arraycopy

Exception raised during rendering: java.lang.System.arraycopy 本文地址: http://blog.csdn.net/caroline_wendy Error: Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V 错误导致UI无法显示,原因是Android的SDK使用Level20的可穿戴版本,下载其它的SDK即可. 基本原因是Android S

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

在布局添加控件手动添加还是拖的添加,添加edittext后布局就不好用,其他控件好用,然后就说下面这段话 Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V Exception details are logged in Window > Show View > Error Log Check the "Android version to use when rendering layouts

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

最近下载一个新版本的adt-bundle,Android API是20. 把Plain Text控件往布局上面拖时,发现拖不上去,出现了下面的错误: 搞不懂是什么原因造成的.后来才知道是因为Android API版本太高造成的,于是用以前的Android API 17,马上就正常了.

java.lang.NoClassDefFoundError: org/eclipse/jetty/util/thread/QueuedThreadPool$1

1.错误描述 [WARNING] FAILED qtp1691065417{8<=8<=8/254,0}: java.lang.NoClassDefFoundError: org/eclipse/jetty/util/thread/QueuedThreadPool$1 [WARNING] FAILED [email protected]: java.lang.NoClassDefFoundError: org/eclipse/jetty/util/thread/QueuedThreadPool

java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager

java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager 问题: 使用Springboot打包为war部署于Tomcat7中报错 java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.get

maven web 项目中启动报错java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener

本篇文章主要介绍了"maven web 项目中启动报错java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener ",主要涉及到maven web 项目中启动报错java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener 方面的内容,对于maven web 项目中启动报错jav