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做特殊处理,如下代码所示:

  1. class User implements Cloneable
  2. {
  3. public Object clone() throws CloneNotSupportedException
  4. {
  5. User cloned = User super.clone();
  6. cloned.birthday = (Date) hireDay.clone()
  7. return cloned;
  8. }
  9. }
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。

原文出处:http://pengcqu.iteye.com/blog/493120

java中clone的深入理解的更多相关文章

  1. 分析java中clone()方法 (转载+修改)

    Java中的clone() 方法 java所有的类都是从java.lang.Object类继承而来的,而Object类提供下面的方法对对象进行复制. protected native Object c ...

  2. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  3. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  4. Java中的Cloneable接口理解

    Cloneable接口是一个标记接口,也就是没有任何内容,定义如下: 这里分析一下这个接口的用法,clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类 ...

  5. 微冷的雨之Java中的多线程初理解(一)

    在讲解多线程前,我们必须理解什么是多线程?而且很多人都会将进程和线程做对比. 进程和线程 进程:进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在 ...

  6. 对Java中字符串的进一步理解

    字符串在程序开发中无处不在,也是用户交互所涉及到最频繁的数据类型,那么字符串不仅仅就是我们简单的理解的String str = "abc";一起来更加深入的看一下 在Java中,字 ...

  7. Java中的ThreadLocal深入理解

    提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...

  8. Java学习疑惑(8)----可视化编程, 对Java中事件驱动模型的理解

    我们编写程序就是为了方便用户使用, 我觉得UI设计的核心就是简洁, 操作过于繁琐的程序让很大一部分用户敬而远之. 即使功能强大, 但是人们更愿意使用易于操作的软件. 近年流行起来的操作手势和逐渐趋于成 ...

  9. java中回调函数的理解

    一,案例一 "通常大家说的回调函数一般就是按照别人(李四)的定好的接口规范写,等待别人(张三)调用的函数,在C语言中,回调函数通常通过函数指针来传递:在Java中,通常就是编写另外一个类或类 ...

随机推荐

  1. Vim的常用命令笔记

    [简介] Vim是vi编辑器的改进版.vi是类UNIX系统里最常用的编辑器. [模式] 在shell中直接打vim filename就会进入普通模式.按i键进入编辑模式,此时Vim底部显示INSERT ...

  2. spring mvc 和 jstl

    spring ,jstl 在maven配置文件的配置:<dependency><groupId>org.springframework</groupId><a ...

  3. c++ split模板实现

    模板实现,重载+6: template<typename _Elem, typename _Fty> inline void split(const _Elem* s, const _El ...

  4. C#2.0--集合--转载车老师

    集合在编程的过程中用的是非常的多,如GridViewRowCollection.ConnectionStringSettingsCollection.NameValueCollection等等.一般来 ...

  5. FireMonkey Style Designer

    http://docwiki.embarcadero.com/RADStudio/Berlin/en/FireMonkey_Style_Designer http://docwiki.embarcad ...

  6. MYSQL查询表结构

    mysql查看表结构命令,如下: desc 表名;show columns from 表名;describe 表名;show create table 表名; use information_sche ...

  7. MongoDB shell操作

    shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用JavaScript脚本完成操作的.使用shell 命令,需要启动mongo.exe. 常用shell命令如下: 1. ...

  8. 一道c++小编程题,

    题目: 编写一个小程序,从标准输入读入一系列string对象,寻找连续重复出现的单词,程序应该找出满足以下条件的单词的输入位置:该单词的后面紧跟着再次出现自己本身,跟 踪重复次数量多的单词及其重复次数 ...

  9. 深入浅出Hadoop实战开发(HDFS实战图片、MapReduce、HBase实战微博、Hive应用)

    Hadoop是什么,为什么要学习Hadoop?     Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运 ...

  10. Swift - 给表格添加移动单元格功能(拖动行)

    1,下面的样例是给表格UITableView添加单元格移动功能: (1)给表格添加长按功能,长按后表格进入编辑状态  (2)在编辑状态下,可以看到单元格后面出现拖动按钮  (3)鼠标按住拖动按钮,可以 ...