学而不思则罔,思而不学则殆
【Java】System.arraycopy
java源码
/**
* @param src 原数组,被拷贝的数组
* @param srcPos 原数组起始位置
* @param dest 目标数组
* @param destPos 从目标数组那个索引位置开始拷贝
* @param length 长度
* Throws:
* IndexOutOfBoundsException – if copying would cause access of data outside array bounds.
* ArrayStoreException – if an element in the src array could not be stored into the dest array because of a type mismatch.
* NullPointerException – if either src or dest is null.
*/
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
* @param src 原数组,被拷贝的数组 * @param srcPos 原数组起始位置 * @param dest 目标数组 * @param destPos 从目标数组那个索引位置开始拷贝 * @param length 长度
其中src和dest都必须是同类型或者可以进行转换类型的数组
测试
测试一-全部复制
private static void testStringArray1() {
String[] strings1 = {"a", "b", "c", "d", "e"};
String[] strings2 = new String[strings1.length];
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, null, null, null]
System.arraycopy(strings1, 0, strings2, 0, 5);
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[a, b, c, d, e]
}
原数组和目标数组都从0开始复制,长度为5
测试二-局部复制一
private static void testStringArray2() {
String[] strings1 = new String[]{"a", "b", "c", "d", "e"};
String[] strings2 = new String[strings1.length];
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, null, null, null]
System.arraycopy(strings1, 0, strings2, 2, 3);
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, a, b, c]
}
原数组从下标0开始,目标数组从下标2开始复制3个元素
测试二-局部复制二
private static void testStringArray3() {
String[] strings1 = new String[]{"a", "b", "c", "d", "e"};
String[] strings2 = new String[strings1.length];
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, null, null, null]
System.arraycopy(strings1, 2, strings2, 0, 3);
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[c, d, e, null, null]
}
原数组从下标2开始,目标数组从下标0开始复制3个元素
测试三-深拷贝还是浅拷贝
static class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
private static void testStringArray3() {
Person[] people1 = new Person[]{
new Person("zy", 28),
new Person("wxf", 18),
new Person("my", 56),
new Person("mht", 49)
};
Person[] people2 = new Person[people1.length];
System.out.println("people1:" + Arrays.toString(people1));
System.out.println("people2:" + Arrays.toString(people2));
System.arraycopy(people1, 0, people2, 0, 4);
System.out.println("people1:" + Arrays.toString(people1));
System.out.println("people2:" + Arrays.toString(people2));
for (int i = 0; i < people1.length; i++) {
System.out.println(people1[i] == people2[i]);
}
}
测试如下:
people1:[com.test.SystemArrayTest$Person@2503dbd3, com.test.SystemArrayTest$Person@4b67cf4d, com.test.SystemArrayTest$Person@7ea987ac, com.test.SystemArrayTest$Person@12a3a380]
people2:[null, null, null, null]
people1:[com.test.SystemArrayTest$Person@2503dbd3, com.test.SystemArrayTest$Person@4b67cf4d, com.test.SystemArrayTest$Person@7ea987ac, com.test.SystemArrayTest$Person@12a3a380]
people2:[com.test.SystemArrayTest$Person@2503dbd3, com.test.SystemArrayTest$Person@4b67cf4d, com.test.SystemArrayTest$Person@7ea987ac, com.test.SystemArrayTest$Person@12a3a380]
true
true
true
true
两个数组中都是同一个对象,所有是浅拷贝,浅拷贝拷贝的是对象的引用,如果对象里面是基本类型也没有影响,应为我们拷贝的是对象的引用。
测试四- 超出大小限制
String[] strings1 = new String[]{"a", "b", "c", "d", "e"};
String[] strings2 = new String[strings1.length];
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, null, null, null]
System.arraycopy(strings1, 0, strings2, 0, 7);
System.out.println("string1:" + Arrays.toString(strings1));
System.out.println("string2:" + Arrays.toString(strings2));
string1:[a, b, c, d, e]
string2:[null, null, null, null, null]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at com.test.SystemArrayTest.testStringArray4(SystemArrayTest.java:104)
at com.test.SystemArrayTest.main(SystemArrayTest.java:11)
测试五-空对象异常
String[] strings1 = new String[]{"a", "b", "c", "d", "e"};
String[] strings2 = new String[strings1.length];
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, null, null, null]
strings2 = null;
System.arraycopy(strings1, 0, strings2, 0, 5);
System.out.println("string1:" + Arrays.toString(strings1));
System.out.println("string2:" + Arrays.toString(strings2));
string1:[a, b, c, d, e]
string2:[null, null, null, null, null]
Exception in thread "main" java.lang.NullPointerException
at java.lang.System.arraycopy(Native Method)
at com.test.SystemArrayTest.testStringArray5(SystemArrayTest.java:127)
at com.test.SystemArrayTest.main(SystemArrayTest.java:12)
测试六 - 类型不匹配
String[] strings1 = new String[]{"a", "b", "c", "d", "e"};
Integer[] strings2 = new Integer[strings1.length];
System.out.println("string1:" + Arrays.toString(strings1));//string1:[a, b, c, d, e]
System.out.println("string2:" + Arrays.toString(strings2));//string2:[null, null, null, null, null]
System.arraycopy(strings1, 0, strings2, 0, 5);
System.out.println("string1:" + Arrays.toString(strings1));
System.out.println("string2:" + Arrays.toString(strings2));
String和Integer不能copye
string1:[a, b, c, d, e]
string2:[null, null, null, null, null]
Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at com.test.SystemArrayTest.testStringArray6(SystemArrayTest.java:150)
at com.test.SystemArrayTest.main(SystemArrayTest.java:13)
测试七-父类向子类copy
static class Base { }
static class Child extends Base { }
//类型兼容测试
private static void testStringArray7() {
Base[] bases = new Base[]{new Base(), new Base()};
Child[] children = new Child[bases.length];
System.out.println("bases:" + Arrays.toString(bases));
System.out.println("children:" + Arrays.toString(children));
System.arraycopy(bases, 0, children, 0, 2);
System.out.println("bases:" + Arrays.toString(bases));
System.out.println("children:" + Arrays.toString(children));
}
bases:[com.test.SystemArrayTest$Base@2503dbd3, com.test.SystemArrayTest$Base@4b67cf4d]
children:[null, null]
Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at com.test.SystemArrayTest.testStringArray7(SystemArrayTest.java:173)
at com.test.SystemArrayTest.main(SystemArrayTest.java:14)
测试八-子类向父类copy
//类型兼容测试
private static void testStringArray8() {
Child[] children = new Child[]{new Child(), new Child()};
Base[] bases = new Base[children.length];
System.out.println("bases:" + Arrays.toString(bases));
System.out.println("children:" + Arrays.toString(children));
System.arraycopy(children, 0, bases, 0, 2);
System.out.println("bases:" + Arrays.toString(bases));
System.out.println("children:" + Arrays.toString(children));
}
bases:[null, null]
children:[com.test.SystemArrayTest$Child@2503dbd3, com.test.SystemArrayTest$Child@4b67cf4d]
bases:[com.test.SystemArrayTest$Child@2503dbd3, com.test.SystemArrayTest$Child@4b67cf4d]
children:[com.test.SystemArrayTest$Child@2503dbd3, com.test.SystemArrayTest$Child@4b67cf4d]
所以src和dest都必须是同类型或者可以进行转换类型的数组,理解就是:子类可以复制到父类,但是父类不能复制成为子类。向下兼容。