`
dcriori
  • 浏览: 95363 次
社区版块
存档分类
最新评论

关于java中克隆的学习(二)

阅读更多

第一部分说了传值的问题,今天接着来看clone的问题。

package dcr.study.test.clone;

import java.util.Date;

/*
 * 在实际编程中我们会遇到一种问题,比如,我们有一个客户,他每次来订货,订单上的商品几乎都是一样的
 * 这时每次去录入商品,显然很烦,这个时候,我要参照以往的单据去创建一张新的订单。然后做些细微的修
 * 改,这样就不用每次去录这个客户的信息和商品。
 * 
 * 这种情况,用简单的赋值语句,不太好。有很多方法去实现这个需求,但用clone应该是一个比较好的方式。
 * 
 * 
 *  这里值得注意的是Obj必须实现Cloneable接口,否则在使用clone方法的时候,会报
	java.lang.CloneNotSupportedException异常
	这里我们发现Cloneable接口是一个抽象接口,是不包含任何方法的
	public abstract interface java.lang.Cloneable {}
	其实这个接口仅仅是一个标志,而且这个标志也仅仅是针对Object类中clone()方法的,
	如果clone类没有实现Cloneable接口,并调用了Object的clone()方法
	(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出 
	CloneNotSupportedException异常。 
 * */
public class OrderClone implements Cloneable{
	private String buyer;
	private Date date;
	private int number;
	public String getBuyer() {
		return buyer;
	}
	public void setBuyer(String buyer) {
		this.buyer = buyer;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	
	public Object clone(){
		OrderClone o = null;
		try {
			o = (OrderClone)super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return o;
	}
}
 
package dcr.study.test.clone;
/*
 * 没有实现克隆接口
 * */
public class UnCloneA {
	private int i;

	public UnCloneA(int ii) {
		i = ii;
	}

	public void doublevalue() {
		i *= 2;
	}

	public String toString() {
		return Integer.toString(i);
	}
}
 

 

package dcr.study.test.clone;

public class CloneB implements Cloneable {
	public int aInt;
	public UnCloneA unCA = new UnCloneA(123);

	public Object clone() {
		CloneB o = null;
		try {
			o = (CloneB) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return o;
	}
}

 

package dcr.study.test.clone;

import java.sql.Date;
/*总结:
   Clone()方法的使用比较简单,注意如下几点即可:
a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,
    基本型别还是reference variable
b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的
    时候会抛出CloneNotSupportedException。如果仔细看你会发现Cloneable接口只是个抽象接口
    并没有任何方法,他只是个标记。 
 * */
public class OrderTest {
	
	public static void main(String[] args) {
		OrderClone o1= new OrderClone();
		o1.setBuyer("dcriori");
		o1.setDate(new Date(0));
		o1.setNumber(10000);
		
		OrderClone o2 = o1;
		OrderClone o3 = (OrderClone) o1.clone();
		
		o2.setBuyer("sagaris");
		o2.setNumber(20000);
		
		System.out.println("O1  \nBuyer:"+o1.getBuyer()+"\nDate:" 
				+ o1.getDate() + "\nNumber:" + o1.getNumber());
		System.out.println("O2  \nBuyer:"+o2.getBuyer()+"\nDate:" 
				+ o2.getDate() + "\nNumber:" + o2.getNumber());
		System.out.println("O3  \nBuyer:"+o3.getBuyer()+"\nDate:" 
				+ o3.getDate() + "\nNumber:" + o3.getNumber());
		/*
		 * 运行结果:
		 *  O1  
			Buyer:sagaris
			Date:1970-01-01
			Number:20000
			O2  
			Buyer:sagaris
			Date:1970-01-01
			Number:20000
			O3  
			Buyer:dcriori
			Date:1970-01-01
			Number:10000
			
			通过运行结果我们发现 OrderClone o2 = o1;o2是通过赋值创建的对象,o2在改变的时候,把o1也改
			掉了,这不是我们想要的结果。但o3没有变,说明用clone创建出来的对象,和原来的对象没指向同一块
			内存。
			
		 * */
		System.out.println("============================================");
		System.out.println("=============下面是影子克隆的情况===============");
		System.out.println("============================================");
		
		CloneB b1 = new CloneB();
		b1.aInt = 11;
		System.out.println("before clone,b1.aInt = "+ b1.aInt);
		System.out.println("before clone,b1.unCA = "+ b1.unCA);

		CloneB b2 = (CloneB)b1.clone();
		b2.aInt = 22;
		b2.unCA.doublevalue();
		System.out.println("=================================");
		System.out.println("after clone,b1.aInt = "+ b1.aInt);
		System.out.println("after clone,b1.unCA = "+ b1.unCA);
		System.out.println("=================================");
		System.out.println("after clone,b2.aInt = "+ b2.aInt);
		System.out.println("after clone,b2.unCA = "+ b2.unCA); 
		/*    ============================================
			=============下面是影子克隆的情况===============
			============================================
			before clone,b1.aInt = 11
			before clone,b1.unCA = 123
			=================================
			after clone,b1.aInt = 11
			after clone,b1.unCA = 246
			=================================
			after clone,b2.aInt = 22
			after clone,b2.unCA = 246
 		 * 这里我们发现,类CloneB虽然实现了Cloneable接口,也写了Clone方法,但是由于使用了其它未
		 * 实现Cloneable接口的类UnCloneA因此在改变b2的unCA的值的时候,把b1的unCA的值也改掉了
		 * 这说明在clone的时候,对于基础类型没有什么问题,但是对于类类型,问题就来了,我们知道它们
		 * 保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。
		 * 
		 * 解决这个问题的办法,就是深度clone,
		 * 其实说起来也很简单,两个方法,
		 * 一是把UnCloneA类也实现Cloneable接口,重载clone()方法;
		 * 二是在CloneB的clone()方法中加入一句o.unCA = (UnCloneA)unCA.clone();
		 * 代码就不再写了。
		 * */
	}

}

 

 

分享到:
评论

相关推荐

    java 深克隆与浅克隆

    学习java深克隆与浅克隆,希望对你有用

    java代码-使用java解决克隆问题的源代码

    java代码-使用java解决克隆问题的源代码 ——学习参考资料:仅用于个人学习使用!

    实例分析java对象中浅克隆和深克隆

    在本篇文章中我们给大家分享了关于java对象中浅克隆和深克隆的相关知识点和相关代码内容,有兴趣的朋友们学习下。

    java最新面试题50道精讲

    1 、解释一下什么是Java中的对象克隆,以及如何实现? 2 、解释一下Java中的多态性是什么,以及它如何实现? 3 、解释一下Java中的异常处理机制,以及如何处理异常? 4 、解释一下Java中的集合框架是什么,以及它有...

    Thinking in Java简体中文(全)

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    java联想(中文)

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    C#和JAVA的比较

    然而,不管它自己宣称的是什么,许多人认为C#更像是Java的一种克隆,或者是Microsoft用来替代Java的产品。事实是否是这样的呢? 本文的比较结果表明,C#不止是Java的同胞那么简单。如果你是一个Java开发者,想要...

    java——让学员少走弯路

    Java的一些基本概念,Java的起源、为什么我们要学习Java语言,Java跨平台原理剖析;Java环境变量的配置,初学者常犯的问题,Java语言的基本数据类型和Java的语句。 Java中包的概念,类的说明符、方法的说明符、对象...

    Thinking in Java 中文第四版+习题答案

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的...

    Java中对象的序列化方式克隆详解

    在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走...这篇文章主要给大家介绍了Java中对象的序列化方式克隆,需要的朋友可以参考借鉴,下面来一起看看吧。

    本科毕业设计项目,java课程设计,使用Vue+SpringBoot开发的图书管理系统,web全栈开发,适合个人学习、参考

    一套完整的增删改查,适合初学者克隆学习并长期增强维护。(前端代码打包后继承在了SpringBoot中) 安装 需要一个叫做book的数据库,sql我已经上传在根目录, 自行导入,修改application.yml中的数据库连接配置。 ...

    java 编程入门思考

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    Java经典编程源码基础例程300.zip

    Java经典编程源码例程,可以做为你的学习设计参考。 第1章 Java语言概述 1 实例001 输出“Hello World” 2 实例002 输出控制台传递的参数 2 实例003 输出由“*”组成的三角形 3 实例004 输出符号表情 5 第2章 ...

    Java开发详解.zip

    000000_【课程介绍 —— 写在前面的话】_Java学习概述笔记.pdf 010101_【第1章:JAVA概述及开发环境搭建】_JAVA发展概述笔记.pdf 010102_【第1章:JAVA概述及开发环境搭建】_Java开发环境搭建笔记.pdf 010201_【第2...

    Java初学者入门教学

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    深入了解Java对象的克隆

    主要介绍了Java对象的克隆的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下

    C#和 Java比较

    然而,不管它自己宣称的是什么,许多人认为C#更像是Java的一种克隆,或者是Microsoft用来替代Java的产品。事实是否是这样的呢? 本文的比较结果表明,C#不止是Java的同胞那么简单。如果你是一个Java开发者,想要...

    物理不可克隆函数综述

    首先,根据迄今为止研究人员提出的 PUF 的各种不同实现方法,分类概括出其详细的设计, 并总结出当前仍然面临的... 最后,从密码学应用的角度,讨论了 PUF 的应用方向,并展望了关于 PUF 未来的几个有意 义的研究方向。

    JAVA_Thinking in Java

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    基于JAVA的搜索引擎 lucene-2.2.0

    在前面Lucene-2.2.0 源代码阅读学习(1)中,根据Lucene提供的一个Demo,详细分析研究一下索引器org.apache.lucene.index.IndexWriter类,看看它是如果定义的,掌握它建立索引的机制。 通过IndexWriter类的实现源代码...

Global site tag (gtag.js) - Google Analytics