JAVA中浅克隆和深克隆
1 浅克隆和深克隆的区别
1、浅克隆:对当前对象进行克隆,并克隆该对象所包含的8种基本数据类型和String类型属性(拷贝一份该对象并重新分配内存,即产生了新的对象);但如果被克隆的对象中包含除8中数据类型和String类型外的其他类型的属性,浅克隆并不会克隆这些属性(即不会为这些属性分配内存,而是引用原来对象中的属性)。
2、深克隆:深克隆是在浅克隆的基础上,递归地克隆除8种基本数据类型和String类型外的属性(即为这些属性重新分配内存而非引用原来对象中的属性)
2 浅克隆与深克隆的特点
1、被克隆的对象的类应实现 Cloneable 接口,并重写 clone() 方法
2、浅克隆中由于除8中数据类型和String类型外的其他类型的属性不会被克隆,因此当通过新对象对这些属性进行修改时,原对象的属性也会同时改变。而深克隆则已经对这些属性重新分配内存,所以当通过新对象对这些属性进行修改时,原对象的属性不会改变。
3 测试
1.浅克隆
Dogs

package images; public class Dogs implements Cloneable{ private int id; private Cat cat; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public Dogs(int id) { this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } @Override public String toString() { return "Dogs{" + "id=" + id + ", " + cat.toString() + '}'; } }
Cat

package images; public class Cat { private int id; private String name; public Cat(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Cat{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
Test:

package images; public class Test { public static void main(String[] args) { Dogs dog1=new Dogs(1); Cat cat1=new Cat(1,"cat1"); dog1.setCat(cat1); try { Dogs dog2= (Dogs) dog1.clone(); dog2.setId(2); System.out.println("dog1ID:"+dog1.getId()+" dog2ID:"+dog2.getId());//dog1ID:1 dog2ID:2 dog2.getCat().setId(2); System.out.println(dog1.getCat().getId()+" "+dog2.getCat().getId());//2 System.out.println(dog1.getClass()==dog2.getClass());//true System.out.println(dog1.getCat().getClass()==dog2.getCat().getClass());//true System.out.println(dog1==dog2);//false System.out.println(dog1.getCat()==(dog2.getCat()));//true } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
2 深克隆
Dogs

package images; import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; import java.io.*; import java.util.Arrays; public class Dogs implements Cloneable, Serializable { private int id; private Cat cat; @Override protected Object clone() throws CloneNotSupportedException { try { //序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); //写入到当前类(也可以写入到文件) oos.writeObject(this); //反序列化 ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); return (Object) ois.readObject(); } catch ( Exception e) { System.out.println("克隆出错"+ Arrays.toString(e.getStackTrace())); return null; } } public Dogs(int id) { this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } @Override public String toString() { return "Dogs{" + "id=" + id + ", " + cat.toString() + '}'; } }
Cat

package images; import java.io.Serializable; public class Cat implements Cloneable, Serializable { private int id; private String name; public Cat(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Cat{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
Test:

package images; public class Test { public static void main(String[] args) { try { Dogs dog1=new Dogs(1); Cat cat1=new Cat(1,"cat1"); dog1.setCat(cat1); Dogs dog2= (Dogs) dog1.clone(); dog2.setId(2); System.out.println("dog1ID:"+dog1.getId()+" dog2ID:"+dog2.getId());//dog1ID:1 dog2ID:2 dog2.getCat().setId(2); System.out.println(dog1.getCat().getId()+" "+dog2.getCat().getId());//1 2 System.out.println(dog1.getClass()==dog2.getClass());//true System.out.println(dog1.getCat().getClass()==dog2.getCat().getClass());//true System.out.println(dog1==dog2);//false System.out.println(dog1.getCat()==(dog2.getCat()));//false } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
4 总结
深克隆的实现有两种方式:
①实现Cloneable接口并重写Object类中的clone()方法;
②实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了