- 浏览: 771003 次
- 性别:
- 来自: 未来
最新评论
-
StormFeng:
StormFeng 写道测试,ArrayList的性能在0.1 ...
Java中ArrayList和LinkedList区别 -
StormFeng:
测试,ArrayList的性能在0.17秒,而linkedli ...
Java中ArrayList和LinkedList区别 -
INexter:
大哥!!!binarySearch 有个大前提就是先是有序的, ...
Java中ArrayList和LinkedList区别 -
honey_fansy:
楼下新增的测试都不准,都没有一定的前提:ArrayList需要 ...
Java中ArrayList和LinkedList区别 -
Nabulio:
Mark太少了
Java中Collection和Collections的区别
面试中经常遇到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做特殊处理,如下代码所示:
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。
理解有误之处,还望高 手 指 点!
相关链接:
全球软件项目外包平台 兼职做外包 挣Money!
评论
package com.colorme.t20.deepclone;
/**
* 被克隆对象里包含的引用类
* @author 王经纬
* @version 2008-8-29
*/
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 王经纬
* @version 2008-8-29
*/
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());
}
}
}
我给你补充一点!
package com.model.t22.simple;
public class Student implements Cloneable{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package com.model.t22.simple;
public class SimpleTest {
public static void main(String[] args) {
Student s = new Student();
s.setAge(30);
s.setName("zhangsan");
System.out.println("克隆之前的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之前的原始对象名字值是:"+s.getName());
System.out.println("开始克隆。。。。");
try {
Student sClone = (Student)s.clone();
sClone.setAge(80);
sClone.setName("lisi");
System.out.println("克隆以后的对象的值是:"+sClone.getAge());
System.out.println("克隆以后的对象的值是:"+sClone.getName());
System.out.println("克隆之后的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之后的原始对象名字值是:"+s.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
非常感谢!
我给你补充一点!
package com.model.t22.simple;
public class Student implements Cloneable{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package com.model.t22.simple;
public class SimpleTest {
public static void main(String[] args) {
Student s = new Student();
s.setAge(30);
s.setName("zhangsan");
System.out.println("克隆之前的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之前的原始对象名字值是:"+s.getName());
System.out.println("开始克隆。。。。");
try {
Student sClone = (Student)s.clone();
sClone.setAge(80);
sClone.setName("lisi");
System.out.println("克隆以后的对象的值是:"+sClone.getAge());
System.out.println("克隆以后的对象的值是:"+sClone.getName());
System.out.println("克隆之后的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之后的原始对象名字值是:"+s.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
发表评论
-
通过问答方式学习JDBC
2009-11-05 15:24 3756l. 连接到数据库的方法 ... -
Java知识点汇总
2009-10-26 20:44 26251在Java学习尤其是笔试面试中,经常遇到这些知识点,有些内容 ... -
Java面试中遇到的一些经典算法题目
2009-10-26 20:40 157651.写一个方法,用一个for循环打印九九乘法表 ... -
Java中抽象类和接口的区别
2009-10-24 11:43 4719Abstractclass和interface是Java语言中 ... -
Java中ArrayList和LinkedList区别
2009-10-23 14:52 325813一般大家都知道ArrayList和LinkedList的大致区 ... -
Java 1.6 新特性
2009-10-22 11:02 4612一:Desktop类和System ... -
Java中通过缓冲区提高I/O系能
2009-10-21 11:59 5993我们知道Java中一 ... -
Java中泛型的本质
2009-10-20 15:09 8511泛型在Java中经常用到。泛型在本质上是指类型参数化。所谓类型 ... -
Java中静态变量的适用场景
2009-10-20 00:34 13366Java类中的静态变量在程序运行期间,其内存空间对所有该类的对 ... -
Java类加载原理及类加载器
2009-10-18 20:11 6073Java和其他语言不同的是 ... -
Java操作(DOM、SAX、JDOM、DOM4J)xml方式的四种比较与详解
2009-10-18 11:33 18541)DOM(JAXP Crimson解析器) DOM是用与平台 ... -
Java中HashMap的实现
2009-10-17 00:42 5269HashMap可谓JDK的一大实用工具,把各个Object映 ... -
Java中Collection和Collections的区别
2009-10-16 13:28 163929今天翻看Java笔试题,发现有这样问题,比较Collectio ... -
Java数组浅析
2009-10-16 13:14 4333数组(array)是相同类型变量的集合,可以使用共同的 ... -
Java代码优化编程
2009-10-16 01:03 11666可供程序利用的资源(内存、CPU时间、网络带宽等)是有限的,优 ... -
Java事件处理机制与“恋爱关系”
2009-10-16 00:43 4171JAVA中事件处理机制是 ... -
Java中的JNDI (Java命名与目录接口)
2009-10-16 00:19 11223JNDI是 Java 命名与 ... -
Java中Comparable和Comparator实现对象比较
2009-10-15 00:03 30204★ Java知识点汇总 全球软件项目外包平台 兼职做外包 ... -
Java中String和StringBuffer的区别
2009-10-14 00:40 17830★ Java知识点汇总 全球软件项目外包平台 兼职做外包 ... -
Java中Heap与Stack的区别
2009-10-13 08:53 80601) Heap是 Stack的一个子集。 2) Sta ...
相关推荐
对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...
对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...
这个源码资源是关于Java中的Object类的讲解案例代码。Object类是所有Java类的根类,它定义了一些常用的方法,例如equals()、hashCode()、toString()等。本案例代码将详细展示Object类的使用方法,并提供一些实际场景...
2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用...
2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用...
2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用...
java中的clone方法有什么作用 面向对象有哪些特征 面向对象的开发方式有什么优点 组合和继承有什么区别 多态的实现机制是什么 重写和重载的区别 抽象类和接口有什么区别 break如果跳出多重循环 final,finally和...
拷贝对象是java中经常会遇到的问题。java中存在两种类型,基础类型和引用类型。...Object对象中提供了一个clone方法,来供我们对java对象进行拷贝。 protected native Object clone() throws CloneNot
必须深入地理解IndexWriter索引器初始化的过程,以及在构造一个IndexWriter索引器过程中涉及到的一些其他的类,应该深入研究这些相关的类的定义。这样才能有助于深化IndexWriter索引器构造的原理机制。 可见,...
2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用...
2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用...
1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...
在Java中我们有几种方式可以创建一个新的对象呢?总共有以下几种方式: new关键字 反射 clone 反序列化 Unsafe.allocateInstance 为了便于说明和理解,下文仅针对new出来的对象进行讨论。
1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...
1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...
2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用...
想必大家对克隆都有耳闻,世界上第一只克隆羊多莉就是利用细胞核移植技术...其实在Java中也存在克隆的概念,即实现对象的复制。本文将尝试介绍一些关于Java中的克隆和一些深入的问题,希望可以帮助大家更好地了解克隆。
HMM模型源代码,非常适合新手使用,理解模型原理,若有问题欢迎咨询本人,一起学习学习!
我希望我对 JavaScript 和 Swift 的理解能让我更轻松地过渡到学习 Java。 待办事项清单 完成书中的练习题 指示 克隆存储库: $ git clone git@github.com:andrewhercules/java-practice.git