
阿里面试官问题:
回答:
(说明:本文针对深克隆和浅克隆的区别和实现方式?这一问题)
立即学习“Java免费学习笔记(深入)”;
Talk is cheap#
最近不止一次遇见深浅克隆(深复制,浅复制)的问题,除了印象中有个clone方法外一脸懵逼!!!克隆(复制)在Java中是一种常见的操作,目的是快速获取一个对象副本。克隆分为深克隆和浅克隆。
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
总之深浅克隆都会在堆中新分配一块区域,区别在于对象属性引用的对象是否需要进行克隆(递归性的)。
Show you my picture#
pos:当前对象的地址;
son:son属性所指向的地址;
FineVoice语音克隆
免费在线语音克隆,1 分钟克隆你的声音,保留口音和所有细微差别。
61 查看详情
name:对象的name属性。

(相关推荐:java入门教程)
Show you my code#
case1:
public class Son implements Serializable , Cloneable{ private String name; private Son son; public Son() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Son getSon() { return son; } public void setSon(Son son) { this.son = son; } @Override public String toString() { return super.toString(); } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}
测试
public static void main(String[] args) throws Exception{// 创建父亲(LiLiu),儿子(LiWu),孙子(LiLiu)并关联Son father = new Son();father.setName("LiSi");Son son = new Son();son.setName("LiWu");Son grandSon = new Son();grandSon.setName("LiLiu");father.setSon(son);son.setSon(grandSon);// 调用clone方法Son fatherCopy = (Son) father.clone();boolean flag1 = fatherCopy==father;boolean flag2 = fatherCopy.getSon() == son;boolean flag3 = fatherCopy.getSon().getSon() == grandSon;// 比较克隆后的地址System.out.println(flag1);// falseSystem.out.println(flag2);// trueSystem.out.println(flag3);// true// 比较Nameflag1= fatherCopy.getName()==father.getName();flag2 = fatherCopy.getSon().getName() == son.getName();flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();System.out.println(flag1);// trueSystem.out.println(flag2);// trueSystem.out.println(flag3);// true//将对象写到流里 ByteArrayOutputStream byteOut=new ByteArrayOutputStream(); ObjectOutputStream objOut=new ObjectOutputStream(byteOut); objOut.writeObject(father);//从流里读出来 ByteArrayInputStream byteIn=new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream objInput=new ObjectInputStream(byteIn); fatherCopy = (Son) objInput.readObject();flag1= fatherCopy==father;flag2 = fatherCopy.getSon() == son;flag3 = fatherCopy.getSon().getSon() == grandSon;System.out.println(flag1);// falseSystem.out.println(flag2);// falseSystem.out.println(flag3);// false// 比较Nameflag1= fatherCopy.getName()==father.getName();flag2 = fatherCopy.getSon().getName() == son.getName();flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();System.out.println(flag1);// falseSystem.out.println(flag2);// falseSystem.out.println(flag3);// false}
从上文代码及运行结果不难看出,如果对象实现Cloneable并重写clone方法不进行任何操作时,调用clone是进行的浅克隆。而使用对象流将对象写入流然后再读出是进行的深克隆。
思考:既然实现Cloneable接口并重写clone接口只能进行浅克隆。但是如果类的引用类型属性(以及属性的引用类型属性)都进行浅克隆,直到没有引用类型属性或者引用类型属性为null时,整体上就形成了深克隆。既对象的引用类型属性和属性的应用类型属性都实现Coloneable,重写clone方法并在clone方法中进行调用。
protected Object clone() throws CloneNotSupportedException { Son result = (Son) super.clone();if (son != null) {result.son = (Son) son.clone();} return result;}
个人认为,在选择深克隆方法时,应根据对象的复杂程度,如引用类型属性是否有多层引用类型属性关系。如果对象只有一层或者两层引用类型的属性,选择思考中所提到的方法较为方便,反之则使用对象流。
更多相关面试题请访问:java面试题及答案
以上就是谈谈你对java中的深克隆和浅克隆的理解的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/569445.html
微信扫一扫
支付宝扫一扫