java面试基础-Java中对Clone的理解
来源:互联网 发布:实验数据分析怎么写 编辑:程序博客网 时间:2024/05/22 11:32
面试中经常遇到Clone的相关知识,今天总算是把Clone理解的比较透彻了!Java中Clone的概念大家应该都很熟悉了,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的?
1. Clone和Copy
假设现在有一个User对象,User u1=new User(“U1001”,“Jason”,25),通
常我们会有这样的赋值User u2=u1,这个时候只是简单了copy了一下reference,u2和u1都指向内存中同一个object,这样u2或者u1的一个操作都可能影响到对方。打个比方,如果我们通过u2.setAge()方法改变了Age域的值,那么u1通过getAge()方法得到的就是修改之后的Age域的值,显然这不是我们愿意看到的。我们希望得到u1的一个精确拷贝,同时两者互不影响,这时候我们就可以使用Clone来满足我们的需求。User u2=u1.clone(),这时会生成一个新的User对象,并且和u1具有相同的属性值和方法。
2. Shallow Clone和Deep Clone
Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。这样,问题就来了咯,以User为例,它里面有一个域birthday不是基本型别的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型别的reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:
这个时候我们就需要进行deep Clone了,对那些非基本型别的域进行特殊的处理,例如本例中的birthday。我们可以重新定义Clone方法,对birthday做特殊处理,如下代码所示:
Java代码 收藏代码
class User implements Cloneable { public Object clone() throws CloneNotSupportedException { User cloned = User super.clone(); cloned.birthday = (Date) hireDay.clone() return cloned; } }
3. Clone()方法的保护机制在Object中Clone()是被申明为protected的,这样做是有一定的道理的,以User类为例,通过申明为protected,就可以保证只有User类里面才能“克隆”User对象,原理可以参考我前面关于public、protected、private的学习笔记。
4. Clone()方法的使用Clone()方法的使用比较简单,注意如下几点即可:a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variableb. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。
来一个深度的,不过这也不深,还可以克到五段,六段!
package com.colorme.t20.deepclone;/*** 被克隆对象里包含的引用类* @author lcc* @version 2017-07-11*/public class ReferencedObject implements Cloneable{ private int i = 0; public ReferencedObject(int i) { this.i = i; } public void doubleValue(){ this.i = 2*this.i; } public int getNumber(){ return this.i; }public Object clone() throws CloneNotSupportedException {return super.clone();}}package com.feixun.t20.deepclone;/*** 带引用的克隆* @author lcc* @version 2017-07-11*/public class ObjectForDeepClone implements Cloneable{ private int i = 0; private ReferencedObject rf = null; public void setNum(int i) { this.i = i; } public void setReferencedObject(ReferencedObject rf){ this.rf = rf; } public int getNumber(){ return this.i; } public ReferencedObject getReferencedObject(){ return this.rf; } // 重写Object的clone public Object clone() throws CloneNotSupportedException { ObjectForDeepClone cloneObject=(ObjectForDeepClone)super.clone(); // 调用引用对象的clone方法 if(rf!=null){ ReferencedObject rfClone = (ReferencedObject)rf.clone(); cloneObject.setReferencedObject(rfClone); } return cloneObject; }} package com.feixun.t20.deepclone;import java.io.Serializable;public class CloneTest { public static void main(String[] args) { ObjectForDeepClone ofsc = new ObjectForDeepClone(); ofsc.setNum(888); ofsc.setReferencedObject(new ReferencedObject(1)); // 开始clone了! ObjectForDeepClone deepCloneObject = null; try { deepCloneObject = (ObjectForDeepClone) ofsc.clone(); } catch (CloneNotSupportedException ex) { System.out.println("Sorry,Clone Not Supported!"); } // 测试clone是否成功 if(deepCloneObject!=null){ System.out.println("before clone"); System.out.println("ObjectForShallowClone get number : " + ofsc.getNumber()); System.out.println("ObjectForShallowClone ReferencedObject get number : "+ofsc.getReferencedObject().getNumber()+"\n"); deepCloneObject.setNum(999); deepCloneObject.getReferencedObject().doubleValue(); System.out.println("after clone"); System.out.println("CloneObject get number : " + deepCloneObject.getNumber()); System.out.println("CloneObject ReferencedObject get number : " + deepCloneObject.getReferencedObject().getNumber()); System.out.println(); System.out.println("ObjectForShallowClone get number : " + ofsc.getNumber()); System.out.println("ObjectForShallowClone ReferencedObject get number : " + ofsc.getReferencedObject().getNumber()); } }}
理解有误之处,还望高 手 指 点!
- java面试基础-Java中对Clone的理解
- Java中对Clone的理解
- Java中对Clone的理解
- Java中对Clone的理解
- 理解java的clone
- java中clone的深入理解
- 对于java中clone()函数的理解
- java中clone的深入理解
- 对java中clone的看法
- 对 Java 中 clone 方法的思考
- 【面试】--java 基础Cloneable 最彻底的clone是什么?
- 深入理解java的clone
- 深入理解java的clone
- 深入理解java的clone
- 深入理解Java的clone
- 深入理解java的clone
- 深入理解java的clone
- 深入理解java的clone
- 【Java】阿里巴巴Java开发手册V1.2.0
- 在Android Stuido中使用Lint
- NDK 调用 so 时的异常问题解决
- 将字符串转变为大小写
- Android 调用系统的分享界面,进行文件分享
- java面试基础-Java中对Clone的理解
- Java 关于重写compareTo方法
- BZOJ 1565: [NOI2009]植物大战僵尸
- LeetCode53 Maximum Subarray
- break,continue,return的解释
- JAVA特性: 多态
- 单片机 相关基础常识(二)
- linux获取命令帮助详解
- 剑指offer-连续子数组的最大和