引用拷贝、浅拷贝、深拷贝
当我们想复制一个对象时,最自然的操作就是直接赋值给另一个变量,这种做法只是,复制了对象的地址,两个变量指向了同一个对象,任意一个变量操作对象的属性,都会影响到另一个变量。 (如下)
Person p1 = new Person(17);
Person p2 = p1; // 直接赋值
p2.age = 20; // 使用 p2 给属性赋值
System.out.println(p1 = p2); // true
System.out.println(p1.age); // 20

这种对同一个对象的操作,当然算不上复制。(所以,引用拷贝并不算是对象拷贝)
我们一般说的对象拷贝,就是指,浅拷贝 和 深拷贝。
先说浅拷贝
public class Object {
protected native Object clone() throws CloneNoSupportedExpection;
}
Object 提供了一个 clone() ,
看名字就知道,它和对象拷贝有关,
该方法的访问修饰符为 protected,
如果子类不重写该方法,并将其声明为 public ,那外部就调用不了,对象的 clone(),
子类在重写时直接调用,Object 的 clone()
public class Demo01 {
public int age;
public Demo01() {
}
public Demo01(int age) {
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 调用
public static void main(String[] args) throws CloneNotSupportedException {
Demo01 d1 = new Demo01(18);
Demo01 clone = (Demo01)d1.clone();
d1.age = 20;
}
}
它是 native 方法,底层已经实现了拷贝对象的逻辑,
这里要注意,子类一定要实现 Cloneable 接口,
否则在调用 clone() 时,就会抛出异常,这是 java 的规定。
现在我们就可以调用 clone() 方法 来复制对象了。
Person p1 = new Person(18);
Person p2 = new Person();
p2.age = 20;
System.out.println(p1 = p2); // false
System.out.println(p1.age); // 18
此时,会发现,两个对象指向的是两个不同的对象,各自改变属性,也不会影响到另一个对象,

看起来效果很好,但是有一个问题:如果拷贝的对象中,有属性是引用类型,那这种浅拷贝的方式
public class Person implements Cloneable {
public int age;
public int[] arr = new int[]{1,2};
public Person() {
}
public Person(int age, int[] arr) {
this.age = age;
this.arr = arr;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

只是会复制该属性的引用地址,即拷贝对象和原对象,都指向了同一个引用类型(对象)
如果对这个属性,进行一些操作,则会影响到另一个对象的属性。
若是想将对象中的引用类型属性也进行拷贝。
那就需要用到 深拷贝了。
简单将代码修改一下
@Override
protected Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
person.arr = this.arr.clone();
return person;
}
克隆出对象之后,然后再对引用类型的属性进行复制。
此时,对象中的属性也指向了不同的实例

引用拷贝、浅拷贝、深拷贝之间的区别!
| 区别 | |
|---|---|
| 引用拷贝 | 只是复制对象的地址,并不会创建一个新对象。 |
| 浅拷贝 | 会创建一个新对象,并进行属性的复制。但是对引用类型的属性,只会复制其地址。 |
| 深拷贝 | 完全复制整个对象,包括引用类型的对象。 |
实际开发中,不建议使用,因为有抛出异常的风险,如果真想让对象提供拷贝功能,那就自己编写吧!
本文来自博客园,作者:走马!,转载请注明原文链接:https://www.cnblogs.com/zou-ma/p/16188080.html

浙公网安备 33010602011771号