深拷贝和浅拷贝是两种常见的对象或数组复制方式。( 深拷贝和浅拷贝就是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用)
浅拷贝指的是新建一个对象,然后将原始对象中的非引用类型数据复制到新对象中,如果原始对象中有引用类型数据,则复制引用地址而不是实际数据。因此,在浅拷贝后新旧对象中的某些属性之间可能会出现相互影响的情况。(查看非引用数据类型和引用数据类型说明文章:引用数据类型和非引用数据类型_失败尽是常态Zzz的博客-CSDN博客)
例如:
class Person {
int age;
String name;
Person(int age, String name) {
this.age = age;
this.name = name;
}
}
Person person1 = new Person(18, "Alice");
Person person2 = new Person(0, null);
person2.age = person1.age; // 浅拷贝 age
person2.name = person1.name; // 浅拷贝 name
System.out.println(person1.age); // 18
System.out.println(person1.name); // "Alice"
System.out.println(person2.age); // 18
System.out.println(person2.name); // "Alice"
person1.age = 20;
person1.name = "Bob";
System.out.println(person1.age); // 20
System.out.println(person1.name); // "Bob"
System.out.println(person2.age); // 20
System.out.println(person2.name); // "Bob" 注意这里的影响!
在上面的例子中,我们把`person1`和`person2`都设置成`Person(18, "Alice")`,然后通过浅拷贝将`age`和`name`的值复制到了`person2`中。现在如果我们修改`person1`的`age`和`name`属性,同时输出`person2`的属性值,你会发现它们也随之被改变了。
与之相对的是深拷贝,它是将原始对象完全复制一份,并新建一个对象来存储这份复制品。深拷贝会递归地复制所有引用对象及其子对象,因此新旧对象各自修改互不影响。例如:
class Person implements Cloneable {
int age;
String name;
Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Person person1 = new Person(18, "Alice");
Person person2 = (Person) person1.clone(); // 深拷贝
System.out.println(person1.age); // 18
System.out.println(person1.name); // "Alice"
System.out.println(person2.age); // 18
System.out.println(person2.name); // "Alice"
person1.age = 20;
person1.name = "Bob";
System.out.println(person1.age); // 20
System.out.println(person1.name); // "Bob"
System.out.println(person2.age); // 18
System.out.println(person2.name); // "Alice" 注意这里没有影响!
在上面的例子中,我们通过在`Person`类中实现`Cloneable`接口并重写其`clone()`方法来实现深拷贝。然后,我们用深拷贝方式将`person1`复制到了`person2`中,并对它们的属性值进行了修改,结果发现新旧对象彼此互不影响。
需要注意的是,在使用Java自带的浅拷贝方法`clone()`时,其中包含的引用类型数据会被复制其引用地址而非数据本身,因此需要特别注意在使用`clone()`方法进行拷贝时处理好有引用类型的数据。如果需要深度拷贝,请使用其他方式完成或自定义`clone()`方法来实现深拷贝。