Java对象clone()的测试
Object中自带native clone()方法.
研究了一下用法.

1 public class DeepCopyTest { 2 3 public static void main(String[] args) throws CloneNotSupportedException { 4 5 test1(); 6 System.out.println("-----------------------------"); 7 test2(); 8 9 } 10 11 static void test1() throws CloneNotSupportedException { 12 Teacher t1 = new Teacher(); 13 t1.settName("LaoLi"); 14 15 Teacher t2 = new Teacher(); 16 t2.settName("LaoWang"); 17 18 Stu stu = new Stu(); 19 stu.setName("name_1"); 20 stu.setAge(23); 21 stu.setScore(129); 22 stu.setTeacher(t1); 23 24 Stu stuCopy = stu.clone(); 25 System.out.println("1:" + stu.toString()); 26 System.out.println("2:" + stuCopy.toString()); 27 28 stuCopy.setName("name_2"); 29 stuCopy.setAge(25); 30 stuCopy.setScore(133); 31 stuCopy.setTeacher(t2); 32 33 34 System.out.println("11:" + stu.toString()); 35 System.out.println("22:" + stuCopy.toString()); 36 37 } 38 39 static void test2() throws CloneNotSupportedException { 40 Teacher t1 = new Teacher(); 41 t1.settName("LaoLi"); 42 43 Teacher t2 = new Teacher(); 44 t2.settName("LaoWang"); 45 46 Stu stu = new Stu(); 47 stu.setName("name_1"); 48 stu.setAge(23); 49 stu.setScore(129); 50 stu.setTeacher(t1); 51 52 Stu stuCopy = stu.clone(); 53 System.out.println("1:" + stu.toString()); 54 System.out.println("2:" + stuCopy.toString()); 55 56 stuCopy.setName("name_2"); 57 stuCopy.setAge(25); 58 stuCopy.setScore(133); 59 stuCopy.getTeacher().settName("LaoKong"); 60 61 62 System.out.println("11:" + stu.toString()); 63 System.out.println("22:" + stuCopy.toString()); 64 65 } 66 67 } 68 69 class Teacher { 70 private String tName; 71 72 public String gettName() { 73 return tName; 74 } 75 76 public void settName(String tName) { 77 this.tName = tName; 78 } 79 80 @Override 81 public String toString() { 82 return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); 83 } 84 } 85 86 class Stu implements Cloneable { 87 private String name; 88 private int age; 89 private Integer score; 90 private Teacher teacher; 91 92 public Teacher getTeacher() { 93 return teacher; 94 } 95 96 public void setTeacher(Teacher teacher) { 97 this.teacher = teacher; 98 } 99 100 public String getName() { 101 return name; 102 } 103 104 public void setName(String name) { 105 this.name = name; 106 } 107 108 public int getAge() { 109 return age; 110 } 111 112 public void setAge(int age) { 113 this.age = age; 114 } 115 116 public Integer getScore() { 117 return score; 118 } 119 120 public void setScore(Integer score) { 121 this.score = score; 122 } 123 124 public Stu clone() throws CloneNotSupportedException { 125 return (Stu) super.clone(); 126 } 127 128 @Override 129 public String toString() { 130 return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); 131 } 132 133 }
执行结果:
1:Stu[name=name_1,age=23,score=129,teacher=Teacher[tName=LaoLi]]
2:Stu[name=name_1,age=23,score=129,teacher=Teacher[tName=LaoLi]]
11:Stu[name=name_1,age=23,score=129,teacher=Teacher[tName=LaoLi]]
22:Stu[name=name_2,age=25,score=133,teacher=Teacher[tName=LaoWang]]
-----------------------------
1:Stu[name=name_1,age=23,score=129,teacher=Teacher[tName=LaoLi]]
2:Stu[name=name_1,age=23,score=129,teacher=Teacher[tName=LaoLi]]
11:Stu[name=name_1,age=23,score=129,teacher=Teacher[tName=LaoKong]]
22:Stu[name=name_2,age=25,score=133,teacher=Teacher[tName=LaoKong]]
基本验证了这样的结论:
基本类型,不变类型可以做到值拷贝效果.不变类型其实是引用发生了变化.
对象类型,实际上是引用拷贝.
设置一个新对象,stuCopy.getTeacher().setName("LaoKong")
引用其实发生了变化.-->指针A指向空间KK, 指针B也指向空间KK, 指针指向的地址KK中的内容替换掉.
而把对象重新设值, stuCopy.setTeacher(t2)
其实是把对象引用的地址指向新的对象. -->指针A指向空间KK, 指针B也指向空间KK, 指针BB指向新的空间KKK.
----------------------------------------------------
/* 浅复制 */ public Object clone() throws CloneNotSupportedException { Prototype proto = (Prototype) super.clone(); return proto; } /* 深复制 */ public Object deepClone() throws IOException, ClassNotFoundException { /* 写入当前对象的二进制流 */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); /* 读出二进制流产生的新对象 */ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现