内容简介:这也是昨天的面试题。当时只说了深拷贝以及浅拷贝,面试官问了两遍还有吗,我很肯定的说就这两种了,面试结束之后查了一下,啪啪打脸。JAVA实现克隆有两种形式
前言
这也是昨天的面试题。
当时只说了深拷贝以及浅拷贝,面试官问了两遍还有吗,我很肯定的说就这两种了,面试结束之后查了一下,啪啪打脸。
正文
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方法
- 序列化对象
三种方法之间互有优缺点,具体采用要根据实际情况。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 浅谈Java克隆
- 如何克隆一个大 Git 项目
- VMware克隆虚拟机过程图示
- 主机ping不通克隆的虚拟机
- VMware 下快速克隆出多个 Linux 环境
- VMware 下快速克隆出多个 Linux 系统
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
How to Design Programs
Matthias Felleisen、Robert Bruce Findler、Matthew Flatt、Shriram Krishnamurthi / The MIT Press / 2001-2-12 / 71.00美元
This introduction to programming places computer science in the core of a liberal arts education. Unlike other introductory books, it focuses on the program design process. This approach fosters a var......一起来看看 《How to Design Programs》 这本书的介绍吧!