在操作基本数据类型时
// 基本类型数组的复制
int[] ints = {1,2,34,45,6,7,8,42};
int[] intss = new int[8];
System.arraycopy(ints, 0, intss,0,8);
System.out.println(Arrays.toString(ints));
输出:
[1, 2, 34, 45, 6, 7, 8, 42]
然后我们修改intss
intss[0]=6;
System.out.println(Arrays.toString(ints));
之后结果依然没有变化。
[1, 2, 34, 45, 6, 7, 8, 42]
如果我们copy了一个引用类型,在修改目标的时候,会把原数组也一起修改
我们先创建一个类叫Dog:
package com.Class;
public class Dog{
int age;
String name;
public Dog(int age, String name) {
// super(); //创建一个无参的对象
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Dog [age=" + age + ", name=" + name + "]";
}
}
然后在另外一个类里new两个Dog[3],进行copy操作,并进行输出;
Dog[] dogs = new Dog[3];
dogs[0] = new Dog(1, "xiaoming");
dogs[1] = new Dog(2, "zhongming");
dogs[2] = new Dog(3, "daming");
Dog[] dogs2 = new Dog[3];
System.arraycopy(dogs, 0, dogs2, 0, 3);
System.out.println(Arrays.toString(dogs));
结果为:
[Dog [age=1, name=xiaoming], Dog [age=2, name=zhongming], Dog [age=3, name=daming]]
然后我们队dogs2进行赋值操作
dogs2[1].setAge(6);
System.out.println(Arrays.toString(dogs));
结果为:[Dog [age=1, name=xiaoming], Dog [age=6, name=zhongming], Dog [age=3, name=daming]]
copy的是基本数据类型,修改目标数组,原数组是不会改变的。而如果是copy引用数据类型,修改目标数组,原数组是会跟着改变的。
总结原因:java中,存在一个栈空间和堆空间还有一个常量池,如下图:
关系是这样的,intss复制了Ints的东西,所以他们指向了同一个常量池,当intss修改时,因为常量池的东西是不能修改的,所以intss相当于只是修改了指向
而当我们是引用类型时:
Dog gods 在栈空间,new的Dog[3]在堆空间,而dogs有一个地址(假如是0x1212)指向堆空间的内存,所以当我们dogs2 copy了dogs 时,其实把dogs的地址也复制了,相当于他们两个指向同一个堆空间。所以我们在修改dogs2时,实质上是修改和dogs一样地址的内容,所以dogs的内容也被修改了。
说白了就是dogs和dogs2指向同一个内容,他们两个的内容是同一个东西。所以修改dogs2 == dogs