楼上的兄台说的都是对的。对于基本数据类型,arr中的{1,2,3,4,5}存放在值栈中。arr1的地址值是一样的。所以没什么区别。arr2指向的是一个新的地址值。但是这些也都是浅层复制。假如我们的数组不是基本数据类型,比如是sduden类型public class Student { String name; int age;
public Student() { }
public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "age=" + age + ", name=" + name ; } }那么对于使用copeof的方式得到的答案也是都会改变 如: Student s1 = new Student("曹操", 18); Student s2 = new Student("刘备",17); Student [] str = {s1,s2}; Student [] str1 = Arrays.copyOf(str, str.length); System.out.println(Arrays.toString(str));//[age=18, name=曹操, age=17, name=刘备] System.out.println(Arrays.toString(str1));//[age=18, name=曹操, age=17, name=刘备] //修改S1的姓名 s1.setName("曹丕"); System.out.println(Arrays.toString(str));//[age=18, name=曹丕, age=17, name=刘备] System.out.println(Arrays.toString(str1));//[age=18, name=曹丕, age=17, name=刘备]
@Override public String toString() { // TODO Auto-generated method stub return "<"+a+">"; } } class Student2 implements Serializable{ int a; public Student2(int a) { super(); this.a = a; }
@Override public String toString() { // TODO Auto-generated method stub return "<"+a+">"; } }
我觉得最好的方法还是看源代码: Arrays的copyof源码: public static int[] copyOf(int[] original, int newLength) { int[] copy = new int[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }你看 int[] copy = new int[newLength];创建一个新的数组,所以说arr和arr1的首地址一致,但是和arr2的不一致。所以改了arr的100,对于arr2没影响,因为他们在不同的内存中。Myeclipse-->ctrl+shift+H-->输入类名--->找源码。
创建的新数组和原来的没有任何关联 只是内容相同而已
String name;
int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "age=" + age + ", name=" + name ;
}
}那么对于使用copeof的方式得到的答案也是都会改变
如:
Student s1 = new Student("曹操", 18);
Student s2 = new Student("刘备",17);
Student [] str = {s1,s2};
Student [] str1 = Arrays.copyOf(str, str.length);
System.out.println(Arrays.toString(str));//[age=18, name=曹操, age=17, name=刘备]
System.out.println(Arrays.toString(str1));//[age=18, name=曹操, age=17, name=刘备]
//修改S1的姓名
s1.setName("曹丕");
System.out.println(Arrays.toString(str));//[age=18, name=曹丕, age=17, name=刘备]
System.out.println(Arrays.toString(str1));//[age=18, name=曹丕, age=17, name=刘备]
所以还是浅层复制
深层复制下
/**
*
*
* 分析浅层复制和深层复制
* 1、浅层复制就是指仅仅只对一个对象的外层进行了复制,但是该对象里面的
* 元素并没有进行复制,而是指向的同一个地址;例子中有关Student1
* 的操作就是用来验证浅层复制的;
*
* 2、浅层复制的好处和坏处:简单、快捷但是隔离性太差,不安全;
*
* 3、深层复制需要使用到IO流的序列化和反序列化,它的复制会完完全全的
* 把一个对象外层和内存的所有内容都复制一份新的出来;
*
* 4、深层复制的好处和坏处:安全但是操作太麻烦,效率太低;
*
*/
public class Demo {
public static void main(String[] args) throws FileNotFoundException,
IOException, ClassNotFoundException {
/*
* 以下代码是浅层复制
*/
Student1 [] s1 = {new Student1(111)};
Student1 [] s2 = s1.clone();
//是否完成了复制
System.out.println(s1==s2);//false
//是否对象里面的内容没有完成复制
System.out.println(s1[0]==s2[0]);//true
//尝试修改s1中的Student元素里的a的值,查看s2中的Student元素的a的值
//是否被改变
s1[0].a = 222;
System.out.println(s1[0]+","+s2[0]);//相同
/*
* 以下代码是深层复制
*/
Student2 [] s3 = {new Student2(333)};
//实例化序列化对象
ObjectOutputStream oos =
new ObjectOutputStream(
new FileOutputStream("c:/student.ser"));
//调用序列化对象来把对象给写入到文件中去
oos.writeObject(s3);
//关流
oos.close();
//实例化反序列化对象
ObjectInputStream ois =
new ObjectInputStream(
new FileInputStream("c:/student.ser"));
//调用反序列化的方法把文件给转为对象
Student2 [] s4 = (Student2[])ois.readObject();
//关流
ois.close();
//上面的代码已经完成了深层复制,来进行验证
//查看两个对象的内容,以及对象是否相等
System.out.println(Arrays.toString(s3));//[<333>]
System.out.println(Arrays.toString(s4));//[<333>]
System.out.println(s3==s4);//false
//上面的结果可以看出,复制成功了外层,开始检验内层是否也成功
s3[0].a = 444;
System.out.println(Arrays.toString(s3));//[<444>]
System.out.println(Arrays.toString(s4));//[<333>]
}
}
class Student1{
int a; public Student1(int a) {
super();
this.a = a;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "<"+a+">";
}
}
class Student2 implements Serializable{
int a; public Student2(int a) {
super();
this.a = a;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "<"+a+">";
}
}
Arrays的copyof源码: public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}你看 int[] copy = new int[newLength];创建一个新的数组,所以说arr和arr1的首地址一致,但是和arr2的不一致。所以改了arr的100,对于arr2没影响,因为他们在不同的内存中。Myeclipse-->ctrl+shift+H-->输入类名--->找源码。
ary2,是你通过方法的调用创建出来的一个新对象,与ary是两个不同的对象,在你改变ary数组中的元素时,ary2是不会发生任何的改变。