您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发

【原】Arrays.copyOf和System.arraycopy的关系和区别

不忘初心 不忘初心 2019-03-17 围观() 评论() 点赞() JAVA开发

简介:实现一个复制数组的功能,java为我们提供了两种API,Arrays.copyOf和System.arraycopy,那么这二者有什么区别呢?又有着什么样的联系

实现一个复制数组的功能,java为我们提供了两种API,Arrays.copyOf和System.arraycopy,那么这二者有什么区别呢?又有着什么样的联系呢?

老规矩,我们直接看源码:

/**
 * Copies the specified array, truncating or padding with nulls (if necessary)
 * so the copy has the specified length.  For all indices that are
 * valid in both the original array and the copy, the two arrays will
 * contain identical values.  For any indices that are valid in the
 * copy but not the original, the copy will contain <tt>null</tt>.
 * Such indices will exist if and only if the specified length
 * is greater than that of the original array.
 * The resulting array is of exactly the same class as the original array.
 *
 * @param <T> the class of the objects in the array
 * @param original the array to be copied
 * @param newLength the length of the copy to be returned
 * @return a copy of the original array, truncated or padded with nulls
 *     to obtain the specified length
 * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
 * @throws NullPointerException if <tt>original</tt> is null
 * @since 1.6
 */
@SuppressWarnings("unchecked")
public static <T> T[] copyOf(T[] original, int newLength) {
    return (T[]) copyOf(original, newLength, original.getClass());
}

这是我们进入到Arrays.copyOf方法看到的代码,由于支持了泛型,所以又重载了一个copyOf方法,第三个参数是第一个参数的class,也就是需要复制的数组类型

/**
 * Copies the specified array, truncating or padding with nulls (if necessary)
 * so the copy has the specified length.  For all indices that are
 * valid in both the original array and the copy, the two arrays will
 * contain identical values.  For any indices that are valid in the
 * copy but not the original, the copy will contain <tt>null</tt>.
 * Such indices will exist if and only if the specified length
 * is greater than that of the original array.
 * The resulting array is of the class <tt>newType</tt>.
 *
 * @param <U> the class of the objects in the original array
 * @param <T> the class of the objects in the returned array
 * @param original the array to be copied
 * @param newLength the length of the copy to be returned
 * @param newType the class of the copy to be returned
 * @return a copy of the original array, truncated or padded with nulls
 *     to obtain the specified length
 * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
 * @throws NullPointerException if <tt>original</tt> is null
 * @throws ArrayStoreException if an element copied from
 *     <tt>original</tt> is not of a runtime type that can be stored in
 *     an array of class <tt>newType</tt>
 * @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]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

大家看到了什么?

对,没错,其实copyOf的底层也是调用了System.arraycopy方法来实现的。

再去看System.arraycopy的源码:

/**
 * Copies an array from the specified source array, beginning at the
 * specified position, to the specified position of the destination array.
 * A subsequence of array components are copied from the source
 * array referenced by <code>src</code> to the destination array
 * referenced by <code>dest</code>. The number of components copied is
 * equal to the <code>length</code> argument. The components at
 * positions <code>srcPos</code> through
 * <code>srcPos+length-1</code> in the source array are copied into
 * positions <code>destPos</code> through
 * <code>destPos+length-1</code>, respectively, of the destination
 * array.
 * <p>
 * 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.
 * <p>
 * If <code>dest</code> is <code>null</code>, then a
 * <code>NullPointerException</code> is thrown.
 * <p>
 * If <code>src</code> is <code>null</code>, then a
 * <code>NullPointerException</code> is thrown and the destination
 * array is not modified.
 * <p>
 * Otherwise, if any of the following is true, an
 * <code>ArrayStoreException</code> is thrown and the destination is
 * not modified:
 * <ul>
 * <li>The <code>src</code> argument refers to an object that is not an
 *     array.
 * <li>The <code>dest</code> argument refers to an object that is not an
 *     array.
 * <li>The <code>src</code> argument and <code>dest</code> argument refer
 *     to arrays whose component types are different primitive types.
 * <li>The <code>src</code> argument refers to an array with a primitive
 *    component type and the <code>dest</code> argument refers to an array
 *     with a reference component type.
 * <li>The <code>src</code> argument refers to an array with a reference
 *    component type and the <code>dest</code> argument refers to an array
 *     with a primitive component type.
 * </ul>
 * <p>
 * Otherwise, if any of the following is true, an
 * <code>IndexOutOfBoundsException</code> is
 * thrown and the destination is not modified:
 * <ul>
 * <li>The <code>srcPos</code> argument is negative.
 * <li>The <code>destPos</code> argument is negative.
 * <li>The <code>length</code> argument is negative.
 * <li><code>srcPos+length</code> is greater than
 *     <code>src.length</code>, the length of the source array.
 * <li><code>destPos+length</code> is greater than
 *     <code>dest.length</code>, the length of the destination array.
 * </ul>
 * <p>
 * Otherwise, if any actual component of the source array from
 * position <code>srcPos</code> through
 * <code>srcPos+length-1</code> cannot be converted to the component
 * type of the destination array by assignment conversion, an
 * <code>ArrayStoreException</code> is thrown. In this case, let
 * <b><i>k</i></b> be the smallest nonnegative integer less than
 * length such that <code>src[srcPos+</code><i>k</i><code>]</code>
 * cannot be converted to the component type of the destination
 * array; when the exception is thrown, source array components from
 * positions <code>srcPos</code> through
 * <code>srcPos+</code><i>k</i><code>-1</code>
 * will already have been copied to destination array positions
 * <code>destPos</code> through
 * <code>destPos+</code><i>k</I><code>-1</code> and no other
 * positions of the destination array will have been modified.
 * (Because of the restrictions already itemized, this
 * paragraph effectively applies only to the situation where both
 * arrays have component types that are reference types.)
 *
 * @param      src      the source array.
 * @param      srcPos   starting position in the source array.
 * @param      dest     the destination array.
 * @param      destPos  starting position in the destination data.
 * @param      length   the number of array elements to be copied.
 * @exception  IndexOutOfBoundsException  if copying would cause
 *               access of data outside array bounds.
 * @exception  ArrayStoreException  if an element in the <code>src</code>
 *               array could not be stored into the <code>dest</code> array
 *               because of a type mismatch.
 * @exception  NullPointerException if either <code>src</code> or
 *               <code>dest</code> is <code>null</code>.
 */
public static native void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);

哇,这注释写的是真的多,不过我们看到方法用了native来修饰,说明这是一个java本地方法,我们没法再继续往下看了,但是有一点,那就是它必须传递一个相同类型的object数组

现在来总结一下二者的区别:

1、Arrays.copyOf是java.util包下面的集合辅助类,System.arraycopy是java.lang下面的本地方法;

2、System.arraycopy复制数组时,目标数组必须先被创建,Arrays.copyOf则不用自己创建目标数组;

一句话概括:

Arrays.copyOf是System.arraycopy的封装实现

Arrays.copyOf和System.arraycopy的关系和区别

特意写错了一个地方,给大家提个醒,在执行这些复制操作的时候,一定要注意下标的位置,否则一不小心就会出错!!!

java数组数组复制

看完文章,有任何疑问,请加入群聊一起交流!!!

很赞哦! ()

文章评论

  • 请先说点什么
    人参与,条评论

请使用电脑浏览器访问本页面,使用手机浏览器访问本页面会导致下载文件异常!!!

雨落无影

关注上方公众号,回复关键字【下载】获取下载码

用完即删,每次下载需重新获取下载码

若出现下载不了的情况,请及时联系站长进行解决

站点信息

  • 网站程序:spring + freemarker
  • 主题模板:《今夕何夕》
  • 文章统计:篇文章
  • 标签管理标签云
  • 微信公众号:扫描二维码,关注我们