目录
一.Clonable接口
实现步骤:
完整代码:
二.深拷贝
实现步骤:
完整代码:
浅拷贝与深拷贝的对比
使用场景建议
完
浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是对象复制的两种方式,主要区别在于对对象内部引用类型字段的处理方式不同。
- 浅拷贝:仅复制对象本身及其基本类型字段的值,对于引用类型字段,复制的是引用地址(即新对象和原对象共享同一块内存)。
- 深拷贝:完全复制对象及其所有字段(包括引用类型字段),新对象与原对象不共享任何内存,彼此独立。
一.Clonable接口
实现步骤:
①创建两个类
public class Test1 {public static void main(String[] args) {Person person1 = new Person(10,"zhangsan");//Person person2 = person1.clone();//最开始点不出来}
}
public class Person {public int age;public String name;public Person(int age, String name) {this.age = age;this.name = name;}@Overridepublic String toString() {return "Person{" +"age=" + age +", name='" + name + '\'' +'}';}
}
②通过 person1 调用 Object类 的 clone 方法 会失败
③重写 Object类 的 clone 方法
( Alt+Insert → Generate → Override Methods → clone() )
④调用 重写 的 clone 方法 的返回值是Object类型,需要强转为(Person)
⑤现在运行会有一个异常
解决方法:
- throws CloneNotSupportedException ( 该内容在重写的clone()方法中 )
- 复制到main方法的后面
⑥现在代码虽然不会报错,但是还会有异常(不支持克隆)
解决方法:在person类 后面加上一个接口(标记接口)
完整代码:
public class Person implements Cloneable {public int age;public String name;public Person(int age, String name) {this.age = age;this.name = name;}@Overridepublic String toString() {return "Person{" +"age=" + age +", name='" + name + '\'' +'}';}@Overrideprotected Object clone()throws CloneNotSupportedException {return super.clone();}
}
public class Test1 {public static void main(String[] args)throws CloneNotSupportedException {Person person1 = new Person(10,"zhangsan");Person person2 = (Person) person1.clone();//最开始点不出来}
}
二.深拷贝
实现步骤:
①创建一个类,包含 Clonable接口 和 clone() 方法
public class Money implements Cloneable{public double money = 9.9;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
并且在Person类中实例一个 Money对象 :m
原理:
- 通过改变 person2.m.money ,看 person1.m.money 是否被修改
- 如果改变 person2.m.money ,person1.m.money也被修改,那么就是浅拷贝,反之则为深拷贝
②再次重写Person类中的clone() 方法
protected Object clone()throws CloneNotSupportedException {//return super.clone();Person tmp = (Person) super.clone();tmp.m = (Money) this.m.clone();return tmp;}
③进行调试
public class Test1 {public static void main(String[] args)throws CloneNotSupportedException {Person person1 = new Person(10,"zhangsan");Person person2 = (Person) person1.clone();//最开始点不出来System.out.println("修改前:"+person1.m.money);System.out.println("修改前:"+person2.m.money);person2.m.money = 99.99;System.out.println("修改后:"+person1.m.money);System.out.println("修改后:"+person2.m.money);}
}
完整代码:
public class Test1 {public static void main(String[] args)throws CloneNotSupportedException {Person person1 = new Person(10,"zhangsan");Person person2 = (Person) person1.clone();//最开始点不出来System.out.println("修改前:"+person1.m.money);System.out.println("修改前:"+person2.m.money);person2.m.money = 99.99;System.out.println("修改后:"+person1.m.money);System.out.println("修改后:"+person2.m.money);}
}
public class Person implements Cloneable {public int age;public String name;public Money m = new Money();public Person(int age, String name) {this.age = age;this.name = name;}@Overridepublic String toString() {return "Person{" +"age=" + age +", name='" + name + '\'' +'}';}@Overrideprotected Object clone()throws CloneNotSupportedException {//return super.clone();Person tmp = (Person) super.clone();tmp.m = (Money) this.m.clone();return tmp;}
}
public class Money implements Cloneable{public double money = 9.9;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
浅拷贝与深拷贝的对比
特性 | 浅拷贝 | 深拷贝 |
---|---|---|
复制范围 | 仅复制对象本身和基本类型字段 | 复制对象及其所有引用类型字段 |
内存占用 | 低(共享引用类型字段) | 高(完全独立) |
修改影响 | 修改引用类型字段会影响原对象 | 修改引用类型字段不影响原对象 |
实现复杂度 | 简单 | 复杂(需递归处理引用类型) |
使用场景建议
- 浅拷贝:适用于对象内部没有引用类型字段,或引用类型字段不可变(如
String
)。 - 深拷贝:适用于对象内部有可变引用类型字段,且需要完全独立副本的场景(如缓存、状态快照等)