首页 / JAVA / 深入理解Java的浅克隆与深克隆
深入理解Java的浅克隆与深克隆
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了深入理解Java的浅克隆与深克隆,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4786字,纯文字阅读大概需要7分钟。
内容图文
![深入理解Java的浅克隆与深克隆](/upload/InfoBanner/zyjiaocheng/788/952102f39dfa4fc8b3628cb52ece187c.jpg)
前言
克隆,即复制一个对象,该对象的属性与被复制的对象一致,如果不使用Object类中的clone方法实现克隆,可以自己new出一个对象,并对相应的属性进行数据,这样也能实现克隆的目的。
但当对象属性较多时,这样的克隆方式会比较麻烦,所以Object类中实现了clone方法,用于克隆对象。
Java中的克隆分为浅克隆与深克隆
一、实现克隆的方式
1.对象的类需要实现Cloneable接口
2.重写Object类中的clone()方法
3.根据重写的clone()方法得到想要的克隆结果,例如浅克隆与深克隆。
二、浅克隆与深克隆的区别
浅克隆:复制对象时仅仅复制对象本身,包括基本属性,但该对象的属性引用其他对象时,该引用对象不会被复制,即拷贝出来的对象与被拷贝出来的对象中的属性引用的对象是同一个。
深克隆:复制对象本身的同时,也复制对象包含的引用指向的对象,即修改被克隆对象的任何属性都不会影响到克隆出来的对象。
例子如下:
class Person implements Cloneable{ private int age; private String name; public Person(int age, String name) { this.age = age; this.name = name; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } @Override protected Person clone() throws CloneNotSupportedException { return (Person)super.clone(); //调用父类的clone方法 } }
测试代码:
public class CloneTest { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(22,"LiLei"); Person newPerson = person.clone(); person.setAge(21); person.setName("HanMeimei"); System.out.println(person.toString()); System.out.println(newPerson.toString()); } }
测试结果:
Person{age=21, name='HanMeimei'} Person{age=22, name='LiLei'}
即在克隆出新的对象后,修改被克隆对象的基本属性,并不会影响克隆出来的对象。但当被克隆的对象的属性引用其他对象时,此时会有不同的结果。
例子如下:
/** * 学生类 */ class Student implements Cloneable{ private String name; private Achievement achievement; //成绩 public Student(String name, Achievement achievement) { this.name = name; this.achievement = achievement; } public void setName(String name) { this.name = name; } public void setAchievement(Achievement achievement) { this.achievement = achievement; } public Achievement getAchievement() { return achievement; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", achievement=" + achievement + '}'; } @Override protected Student clone() throws CloneNotSupportedException { return (Student) super.clone(); } } /** * 成绩类 */ class Achievement implements Cloneable{ private float Chinese; private float math; private float English; public Achievement(float chinese, float math, float english) { Chinese = chinese; this.math = math; English = english; } public void setChinese(float chinese) { Chinese = chinese; } public void setMath(float math) { this.math = math; } public void setEnglish(float english) { English = english; } @Override public String toString() { return "Achievement{" + "Chinese=" + Chinese + ", math=" + math + ", English=" + English + '}'; } @Override protected Achievement clone() throws CloneNotSupportedException { return (Achievement) super.clone(); } }
测试代码:
public class CloneTest { public static void main(String[] args) throws CloneNotSupportedException { Achievement achievement = new Achievement(100,100,100); Student student = new Student("LiLei",achievement); // 克隆出一个对象 Student newStudent = student.clone(); // 修改原有对象的属性 student.setName("HanMeimei"); student.getAchievement().setChinese(90); student.getAchievement().setEnglish(90); student.getAchievement().setMath(90); System.out.println(newStudent); System.out.println(student); } }
测试结果:
Student{name='LiLei', achievement=Achievement{Chinese=90.0, math=90.0, English=90.0}} Student{name='HanMeimei', achievement=Achievement{Chinese=90.0, math=90.0, English=90.0}}
以上现象表明,上述克隆方式为浅克隆,并不会克隆对象的属性引用的对象,当修改被克隆对象的成绩时,克隆出来的对象也会跟着改变,即两个对象的属性引用指向的是同一个对象。
但只要修改一下Student类中重写的clone()方法,即可实现深克隆。
修改代码如下:
@Override protected Student clone() throws CloneNotSupportedException { Student student = (Student) super.clone(); Achievement achievement = student.getAchievement().clone(); student.setAchievement(achievement); return student; }
测试结果:
Student{name='LiLei', achievement=Achievement{Chinese=100.0, math=100.0, English=100.0}} Student{name='HanMeimei', achievement=Achievement{Chinese=90.0, math=90.0, English=90.0}}
即在Student类中的clone()方法中再克隆一次Achievement对象,并赋值给Student对象。
值得一提的是,上文所说的浅拷贝只会克隆基本数据属性,而不会克隆引用其他对象的属性,但String对象又不属于基本属性,这又是为什么呢?
这是因为String对象是不可修改的对象,每次修改其实都是新建一个新的对象,而不是在原有的对象上修改,所以当修改String属性时其实是新开辟一个空间存储String对象,并把引用指向该内存,而克隆出来的对象的String属性还是指向原有的内存地址,所以String对象在浅克隆中也表现得与基本属性一样。
内容总结
以上是互联网集市为您收集整理的深入理解Java的浅克隆与深克隆全部内容,希望文章能够帮你解决深入理解Java的浅克隆与深克隆所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。