了解数组是对象,就应该知道,以下这个并非数组复制:
int[] scores1={1,2,3,4,5,6,7,8,9,0};
int[] scores2 = scores1;
scores2[0]=99;//scores2第一个数改为99
for(int x:scores1) {
System.out.println(x);
}//执行结果第一个数为99
这个程序片段只不过是将 scores1参考的数组对象,也给scores2参考,所以就是同一个数组。如果你要做数组复制,基本做法是另行建立新数组。例如:
int[] scores3 = new int[scores1.length];//数组是对象
for(int i=0;i<scores1.length;i++) {
scores3[i]=scores1[i];
}
在这个程序片段中,建立一个长度与 scores1相同的新数组,再逐一访问索引元素,并指定给 scores3对应的索引位置。事实上,不用自行使用循环做值而可以使用system.arraycopy( )方法,这个方法会使用原生方式复制每个索引元素使用循环来得快:
int[] scores4 = new int[5];
System.arraycopy(scores1, 2, scores4, 0, 5);
for(int y:scores4) {
System.out.print(y);
}//执行结果:34567
System.arraycopy(scores1, 2, scores4, 0, 5);的五个参数分别是来源数组、来源起始索引、目的数组、目的索引、复制长度。JDK6以上,可以:
int[] scores5=Arrays.copyOf(scores1, scores1.length);
另外Java中数组一旦建立,长度就固定了,如果不够只有新建另行复制
int[] scores5=Arrays.copyOf(scores1, scores1.length*2);
多出的10个全部索引参考至0.
数组深层复制
class Clothes{
String color;
char size;
public Clothes(String color,char size) {
this.color=color;//color与构造函数color同名要用this
this.size=size;
}
}
public class Constructor {
public static void main(String[] args) {
Clothes[] c1= {new Clothes("gray", 'M'),new Clothes("black", 'L')};
Clothes[] c2=new Clothes[c1.length];
for(int i=0;i<c1.length;i++) {
c2[i]=c1[i];
}
c2[0].color="red";
System.out.println(c1[0].color);
}
执行结果为red,原因在于循环执行。实际上循环中仅将c1每个索引处所参考的对象,也给c2每个索引来参考,并没有实际复制出clothes对象,术语上来说,这叫作复制参考,或称这个行为是浅层复制( ShallowCopy)。无论
System.arraycopy(scores1, 2, scores4, 0, 5);还是 Arrays.copyOf
都是浅层复制。如果真的要连同对象一同复制,你得自行操作,因为基本上只有自己才知道每个对象复制时,有哪些属性必须复制。例如:
class Clothes{
String color;
char size;
public Clothes(String color,char size) {
// TODO 自动生成的构造函数存根
this.color=color;//color与构造函数color同名要用this
this.size=size;
}
}
public class Constructor {
public static void main(String[] args) {
Clothes[] c1= {new Clothes("gray", 'M'),new Clothes("black", 'L')};
Clothes[] c2=new Clothes[c1.length];
for(int i=0;i<c1.length;i++) {
//c2[i]=c1[i];浅层复制,c1[i]参考对象也给c2参考,指向同一个对象。c2[0].color="red"也改变c1
Clothes c=new Clothes(c1[i].color, c1[i].size);
c2[i]=c;
}
c2[0].color="red";
System.out.println(c1[0].color);
}
执行结果为gray。因为Clothes c=new Clothes是新建的Clothes,并指给c2.