摘要:优点简单易实现缺点无法真正克隆对象深克隆实现通过递归克隆实现代码输出通过序列化实现代码输出结果分析采用深克隆能有效隔离源对象与克隆对象的联系。
本文首发于cartoon的博客
转载请注明出处:https://cartoonyu.github.io/cartoon-blog/post/java/java%E5%AE%9E%E7%8E%B0%E5%85%8B%E9%9A%86%E7%9A%84%E6%96%B9%E6%B3%95/
这也是昨天的面试题。
当时只说了深拷贝以及浅拷贝,面试官问了两遍还有吗,我很肯定的说就这两种了,面试结束之后查了一下,啪啪打脸。
正文JAVA实现克隆有两种形式
浅克隆
深克隆
JAVA将数据类型分为基本数据类型以及引用数据类型,我认为浅克隆与深克隆的区别主要在于对引用类型的成员属性的操作。深度克隆应该递归克隆引用类型的成员属性。
实现Cloneable接口
重写clone方法,调用父类的clone方法
代码
public class Text implements Cloneable{ private int age; private Name name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } @Override protected Object clone(){ try { return super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } } class Name{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Main { public static void main(String[] args){ Name name1=new Name(); name1.setName("name1"); Text t1=new Text(); t1.setAge(12); t1.setName(name1); Text t2=(Text) t1.clone(); System.out.println(t2.getName().getName()); name1.setName("name2"); System.out.println(t2.getName().getName()); } }
输出
name1 name2
结果分析
因为只是直接调用父类的clone方法,没有对成员属性进行处理,所以在修改t1属性name的值时,t2属性name的值也会随之改变。
优点
简单易实现
缺点
无法真正克隆对象
代码
public class Text implements Cloneable{ private int age; private Name name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } @Override protected Object clone(){ Text text=null; try { text=(Text) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } text.setName((Name) text.getName().clone()); return text; } } class Name implements Cloneable{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } }
输出
name1 name1
代码
public class Text implements Serializable{ private static final long serialVersionUID = 8723901148964L; private int age; private Name name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } public Object myClone(){ Text text=null; ByteArrayOutputStream bos=new ByteArrayOutputStream(); try { ObjectOutputStream oos=new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bis); text=(Text)ois.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return text; } } class Name implements Serializable { private static final long serialVersionUID = 872390113109L; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return name; } }
输出
name1 name1
结果分析
采用深克隆能有效隔离源对象与克隆对象的联系。
从实现过程来说,递归克隆存在克隆过程多且复杂的缺点,所以建议采用序列化的方式进行
深克隆。
总结JAVA对象克隆共有两种形式,三种方法
浅克隆
调用clone方法
深克隆
递归调用clone方法
序列化对象
三种方法之间互有优缺点,具体采用要根据实际情况。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77829.html
摘要:不合规的代码示例合规解决方案参阅复制构造函数与克隆也可以参阅应该实现克隆覆盖的类应为并调用下面为引文翻译谈设计与作者的对话,作者首次在上发表,年月日复制构造函数与克隆在你的书中,你建议使用复制构造函数而不是实现和编写。 今天在用 sonar 审核代码, 偶然看到下面的提示:showImg(https://segmentfault.com/img/bVbqioZ?w=858&h=116)...
摘要:主要内容清楚对象克隆的操作结构巩固接口的作用具体内容对象克隆对象克隆指的就是对象的复制操作,在类里面提供有一个专门克隆的方法。此方法上抛出一个异常,如果要使用对象克隆的类没有实现接口,那么就会抛出此异常。 主要内容 清楚对象克隆的操作结构巩固接口的作用具体内容 对象克隆 对象克隆指的就是对象的复制操作,在Object类里面提供有一个专门克隆的方法。 对象克隆:protected Obj...
摘要:定义给出的原型模式定义如下使用原型实例指定将要创建的对象类型,通过复制这个实例创建新的对象。具体原型类角色负责实现复制现有实例并生成新实例的方法。 Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide 系列文章回顾: 设计模式专栏深入理解单例模式深入理解工厂模式 深入理解...
摘要:目录介绍问题汇总具体问题好消息博客笔记大汇总年月到至今,包括基础及深入知识点,技术博客,学习笔记等等,还包括平时开发中遇到的汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善开源的文件是格式的同时也开源了生活博客,从年 目录介绍 00.Java问题汇总 01.具体问题 好消息 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技...
摘要:有一些设计缺陷,其中最大的一个是接口没有方法。这基本上就是你用复制构造函数做的事情。复制构造方法有几个优点,我在本书中有讨论。的方法是非常棘手的。它创建一个对象而不调用构造函数。无法保证它保留构造函数建立的不变量。 前言 在Java API中,可以通过实现Cloneable接口并重写clone方法实现克隆,但Java设计者否定了使用clone创建新对象的方法. 1. clone方法实现...
阅读 2772·2021-11-02 14:42
阅读 3162·2021-10-08 10:04
阅读 1183·2019-08-30 15:55
阅读 1025·2019-08-30 15:54
阅读 2310·2019-08-30 15:43
阅读 1679·2019-08-29 15:18
阅读 862·2019-08-29 11:11
阅读 2362·2019-08-26 13:52