在StringBuffer
、StringBuilder
、ArrayList
,Arrays
等类的源码中有很多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} to the destination array
* referenced by {@code dest}. The number of components copied is
* equal to the {@code length} argument. The components at
* positions {@code srcPos} through
* {@code srcPos+length-1} in the source array are copied into
* positions {@code destPos} through
* {@code destPos+length-1}, respectively, of the destination
* array.
* <p>
* If the {@code src} and {@code dest} arguments refer to the
* same array object, then the copying is performed as if the
* components at positions {@code srcPos} through
* {@code srcPos+length-1} were first copied to a temporary
* array with {@code length} components and then the contents of
* the temporary array were copied into positions
* {@code destPos} through {@code destPos+length-1} of the
* destination array.
* <p>
* If {@code dest} is {@code null}, then a
* {@code NullPointerException} is thrown.
* <p>
* If {@code src} is {@code null}, then a
* {@code NullPointerException} is thrown and the destination
* array is not modified.
* <p>
* Otherwise, if any of the following is true, an
* {@code ArrayStoreException} is thrown and the destination is
* not modified:
* <ul>
* <li>The {@code src} argument refers to an object that is not an
* array.
* <li>The {@code dest} argument refers to an object that is not an
* array.
* <li>The {@code src} argument and {@code dest} argument refer
* to arrays whose component types are different primitive types.
* <li>The {@code src} argument refers to an array with a primitive
* component type and the {@code dest} argument refers to an array
* with a reference component type.
* <li>The {@code src} argument refers to an array with a reference
* component type and the {@code dest} argument refers to an array
* with a primitive component type.
* </ul>
* <p>
* Otherwise, if any of the following is true, an
* {@code IndexOutOfBoundsException} is
* thrown and the destination is not modified:
* <ul>
* <li>The {@code srcPos} argument is negative.
* <li>The {@code destPos} argument is negative.
* <li>The {@code length} argument is negative.
* <li>{@code srcPos+length} is greater than
* {@code src.length}, the length of the source array.
* <li>{@code destPos+length} is greater than
* {@code dest.length}, the length of the destination array.
* </ul>
* <p>
* Otherwise, if any actual component of the source array from
* position {@code srcPos} through
* {@code srcPos+length-1} cannot be converted to the component
* type of the destination array by assignment conversion, an
* {@code ArrayStoreException} is thrown. In this case, let
* <b><i>k</i></b> be the smallest nonnegative integer less than
* length such that {@code src[srcPos+}<i>k</i>{@code ]}
* cannot be converted to the component type of the destination
* array; when the exception is thrown, source array components from
* positions {@code srcPos} through
* {@code srcPos+}<i>k</i>{@code -1}
* will already have been copied to destination array positions
* {@code destPos} through
* {@code destPos+}<i>k</I>{@code -1} 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.
* @throws IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @throws ArrayStoreException if an element in the {@code src}
* array could not be stored into the {@code dest} array
* because of a type mismatch.
* @throws NullPointerException if either {@code src} or
* {@code dest} is {@code null}.
*/
@HotSpotIntrinsicCandidate
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
看源码可以看到方法是用native
修饰,说明这个方法是用C语言实现的,所以速度很快,接下来我们看看各个参数的详细意义
public static native void arraycopy(
Object src, 复制的源数组
int srcPos, 从源数组的那个下标开始
Object dest, 复制的目标数组
int destPos, 从目标数组的那个下标开始
int length 要复制的长度
);
场景一:
public static void main(String[] args) {
String[] src = {"a","b","c","d","e"};
String[] dst = new String[4];
System.arraycopy(src,1,dst,1,3);
System.out.println(Arrays.toString(dst));
}
结果:
[null, b, c, d]
场景二:
public static void main(String[] args) {
String[] src = {"a","b","c","d","e"};
String[] dst = new String[4];
System.arraycopy(src,0,dst,1,3);
System.out.println(Arrays.toString(dst));
}
结果:
[null, a, b, c]
场景三:
public static void main(String[] args) {
String[] src = {"a","b","c","d","e"};
String[] dst = new String[4];
System.arraycopy(src,src.length,dst,1,3);
System.out.println(Arrays.toString(dst));
}
public static void main(String[] args) {
String[] src = {"a","b","c","d","e"};
String[] dst = new String[4];
System.arraycopy(src,0,dst,dst.length,3);
System.out.println(Arrays.toString(dst));
}
结果:
抛出ArrayIndexOutOfBoundsException异常
场景四:
public static void main(String[] args) {
String[] src = {"a","b","c","d","e"};
String[] dst = new String[4];
System.arraycopy(src,0,dst,dst.length,0);
System.out.println(Arrays.toString(dst));
}
结果:
[null, null, null, null]
总结:如何是对数组的复制,删除,增加都有利用这个方法实现,这样效率更好,速度更快
网友评论