黑马程序员_10_java克隆机制
来源:互联网 发布:阿里云域名解析到端口 编辑:程序博客网 时间:2024/05/20 14:27
java克隆机制
克隆(clone):创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。
通俗易懂的说法:将一个已经存在的实例对象,复制成多个实例,而且每个实例对象直接并没有联系,不会改一处,多处改变。也相当于Copy一样。
而克隆机制也分为深克隆(Shallow clone)与浅克隆(Deep clone),下面通过几个实例来演示。
首先:要克隆的类必须实现Cloneable,这是个许可证,么实现该接口,并重写其方法的类不能实现克隆。
1、定义一个类允许克隆。
class Aa implements Cloneable//克隆的前提{ Int i=1;; @override//必须实现的方法protected Object clone() throws CloneNotSupportedException {return super.clone(); }}public class Demo05 {Public static void main(String[] args) throws CloneNotSupportedException {Aa a=new Aa();Aa b=(Aa)a.clone(); Aa c=a;System.out.println(a.i);System.out.println(b.i);System.out.println(c.i);}}
运行结果:
1
1
1
这样的结果很可能产生两种误会,对有没有过基础的会觉得,把a赋给了b和c。
对了解java指针机制的就会说,b和a都指向了a。两者都只对了一半。
下面增加两行代码就明白了;
Aa a=new Aa();Aa b=(Aa)a.clone();Aa c=a;b.i=10;c.i=5;System.out.println(a.i);System.out.println(b.i);System.out.println(c.i)
运行结果:
5
10
5
显而易见,c变量指向了a,而b变量却是将a变量完全复制过来。很多时候我们都想得到某个对象的副本,暂时修改其属性又不能令对象的属性改变,很矛盾,这是这里可以用到clone关键字,但是这种克隆只能算得上浅度克隆(Shallow Clone)。
什么是深克隆?什么事浅克隆?
演示:在Aa这类中多了一个其他类的对象。
class Aa implements Cloneable{int i=1;B field=new B();@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}}class B {int i=1;public int getI() {return i;}public void setI(int i) {this.i = i;}}
然后主程序依旧按照常规克隆;
Aa a=new Aa();Aa b=(Aa)a.clone();b.field.setI(10);System.out.println(a.field.getI());System.out.println(b.field.geitI());
运行结果:
10
10
结果出乎意料,咋么又变成指针机制了?
要知道这些,先要了解Object在调用clone方法的时候都做了些什么。
Object在对某个实施Clone时对其对象一无所知,仅仅只是简单的做了一个Copy的动作,这就是浅克隆。但是在Aa类中却有一个引用型变量,当克隆时候,就把该对象的地址给克隆了,并没有克隆出实力对象。也可以验证下。
System.out.println(a);System.out.println(b);System.out.println(a.field); System.out.println(b.field);运行结果: Aa@7800e9 Aa@83dae1 B@971d55 B@971d55
结果说明,a和b不是同一个对象,但是a对象的成员field与b对象的成员field,却是同一个对象,如图:
从图上可以看出,基本类型被克隆了,但是引用类型变量,却只克隆了地址,这种克隆也称作浅克隆(Shallow Clone)
怎么才能做到深度度克隆呢?
其实很简单,只需要重新定义Clone方法,对B类做特殊处理(Deep Clone)深度克隆;
class Aa implements Cloneable{int i=1;B field=new B();@Overrideprotected Object clone() throws CloneNotSupportedException {Aa temp=(Aa)super.clone();//先克隆主体temp.field=(B)field.clone();//再克隆引用return temp;}}class B implements Cloneable//这个类也要实现克隆标记{int i=1;public int getI() {return i;}public void setI(int i) {this.i = i;} //还要重写克隆方法protected Object clone() throws CloneNotSupportedException {return super.clone();}}这时候在打印:public static void main(String[] args) throws CloneNotSupportedException {Aa a=new Aa();Aa b=(Aa)a.clone();b.field.setI(100);b.i=10;System.out.println(a.i);System.out.println(b.i);System.out.println(a.field.getI());System.out.println(b.field.getI());}
运行结果:
1
10
1
100
现在内存中就是这样的:
这样就可以达到预想的效果,两个实例直接没有关系了。
总结:
Clone机制:存在两种方式。
1、Shallow Clone;这种clone只对基本数据类型有效,对对象内的引用变量无效。
2、Deep Clone;对对象所有成员都有效,前提是这些成员都实现了Cloneable接口
3、使用Clone将会抛出异常。
4、两种方式按自己需求而用,
--------------------------------android培训、java培训、期待与您交流! ------------------------------------ 黑马程序员_10_java克隆机制
- 黑马程序员--对象的克隆
- 黑马程序员_对象克隆
- 黑马程序员 反射机制
- 黑马程序员--反射机制
- 黑马程序员-反射机制
- 【黑马程序员】反射机制
- 黑马程序员 反射机制
- 黑马程序员-反射机制
- 黑马程序员----反射机制
- 黑马程序员 反射机制
- 黑马程序员_OC_ARC机制
- 黑马程序员--多线程机制
- 黑马程序员--反射机制
- 黑马程序员------反射机制
- 黑马程序员------反射机制
- 黑马程序员-------ARC机制
- 黑马程序员-反射机制
- LeetCode(Path Sum and Path Sum 2)
- spring3+hibernate4配置事务管理以及session获取问题。
- jPBC 2.0.0配置与测试(补充版)
- Binary Tree Level Order Traversal II -- LeetCode
- U3D点滴-计时器
- 黑马程序员_10_java克隆机制
- 电脑回收站恢复软件
- 数据库JDBC步骤
- 算法资料汇总(2014.04.11起)
- Sudoku Puzzles - 九宫格(数独)游戏
- 求一个无序数组中的次大数,只遍历一次数组
- ubuntu中如何将终端命令添加到右键
- MongoDB从2.4.9升级到2.6.0记录及PHP的mongo扩展从1.4.5升级到1.5.1
- C#中流写入类StreamWriter的介绍