2019独角兽企业重金招聘Python工程师标准>>>

因为Java方法中对象参数的传递是句柄(引用)传递,所以方法中对句柄的改动会影响到原对象。

很少调用一个方法来处理它的参数,在实际编程中也要避免改变参数的情况。但如果我们需要在一个方法的调用期间修改一个参数,且不打算修改外部实体,就应该在自己方法的内部制作一个那个参数的副本来保护那个参数。

制作对象副本需要使用clone()方法。这个方法在基础类Object 中定义成“protected”模式。所以在希望克隆的任何衍生类中,必须将其覆盖为“public”模式。例如,标准库类Vector 覆盖了 clone(),所以能为 Vector调用clone()。

class Int {private int i;public Int(int ii) { i = ii; }public void increment() { i++; }public String toString() {return Integer.toString(i);}
}
public class Cloning {public static void main(String[] args) {Vector v = new Vector();    //创建Vectorfor(int i = 0; i < 10; i++ )v.addElement(new Int(i));    //添加对象System.out.println("v: " + v);    //第一次输出  Vector v2 = (Vector)v.clone();    //创建Vector的复制for(Enumeration e = v2.elements();   e.hasMoreElements(); )    //对复制的Vector中的对象进行+1操作((Int)e.nextElement()).increment();System.out.println("v: " + v);     //第二次输出}
} 

上面代码涉及到“深拷贝“和”浅拷贝“的问题。这个例子中由于别名问题,原Vector和拷贝的Vector都包含了相同的对象,即两个Vector是完全独立的,但其中容纳的东西相同,这就是”浅拷贝“。”浅拷贝“只拷贝本对象,该对象内部指向的其他对象,以及”其他对象“又指向的另外的对象都不拷贝。

若要“深拷贝”,必须在覆盖的clone()里采取附加的操作。 通常在调用 super.clone()后,为对象内每个句柄都明确调用一个 clone();否则那些句柄会别名变成原始对象的句柄。当然,必须保证对象内的每个句柄自身也都实现了“深拷贝”。

使类具有克隆能力:

因为Object类将clone()定义为”protected", 所以衍生类不做点什么的话,是无法具有克隆能力的(很简单,对象无法调用本类的protected方法)。

1、覆盖clone()方法为public. 

想要类可以克隆,记住两点:

  1. 几乎肯定要调用super.clone();
  2. 将clone()设置为public。

注意:因为Java不可能在衍生之后反而缩小方法的访问范围,所以一旦对象变得可以克隆,从它衍生的任何东西都是可以克隆的。(下面会有一种特殊机制关闭克隆能力)

2、实现Cloneable接口

Cloneable接口是空的,我们不需要为它实现任何方法。它的存在有两个原因:

  • 可能有一个上溯造型句柄指向一个基础类型,而且不知道它是否真的能克隆那个对象。在这种情况下,可用instanceof 关键字调查句柄是否确实同一个能克隆的对象连接。
  • 考虑到我们可能不愿所有对象类型都能克隆。所以Object.clone()会验证一个类是否真的是实现了Cloneable 接口。若答案是否定的,则“掷”出一个 CloneNotSupportedException违例。

所以在一般情况下,我们必须将“implement Cloneable”作为对克隆能力提供支持的一部分。

经过上面两步,就可以创建自己的可克隆的类:

class MyObject implements Cloneable {int i;MyObject(int ii) { i = ii; }public Object clone() {Object o = null;try {o = super.clone();} catch (CloneNotSupportedException e) {System.out.println("MyObject can't clone");}return o;}public String toString() { return Integer.toString(i); }
}

 消除克隆能力:

  1. 不实现 Cloneable 来试着防止克隆,并覆盖clone(),以产生一个违例。这样,从它衍生出来的类的clone()方法调用super.clone()时会抛出异常。
  2. 将类设为final,从而防止克隆。若clone()尚未被我们的任何一个上级类覆盖,这一设想便不会成功。 若已被覆盖,那么再一次覆盖它,并“掷”出一个 CloneNotSupportedException(克隆不支持)违例。为担保克隆被禁止,将类设为final是唯一的办法。

转载于:https://my.oschina.net/HuoQibin/blog/1621183

Java--对象的克隆相关推荐

  1. 【JAVA零基础入门系列】Day14 Java对象的克隆

    [JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...

  2. java,对象的克隆

    这次写的是有关java对象的克隆 首先是 java对象的假克隆 对于基本类型我们可以用"="来进行克隆,此时对于两个变量除了相等没有其他的关系 但对于引用类型来说就不能简单的使用& ...

  3. java对象序列化克隆_JAVA 对象克隆和序列化

    先用一个例子来说明假克隆吧,也就是用"="之后的效果.. [运行结果]: [运行结果] 姓名:rollen年龄:20 姓名:hello world年龄:100 姓名:hello w ...

  4. java对象序列化克隆_Java8基础知识(三)对象克隆与序列化

    对象克隆 对象克隆最简单的方式是:将对原对象的引用直接传给一个新的副本变量.这种方式存在很大的缺陷,两个变量中任何一个变量的改变都会影响另一个变量. 浅拷贝 利用Object类的clone方法,能够创 ...

  5. Java 对象的克隆Clone和必须了解的浅拷贝与深拷贝

    前言 为什么要写这篇文章? 因为我最近无意间看到了一些项目的代码,不管是曾经编码的人还是新接手的人, 在想完全克隆复制一个已经存在的对象,做为后续的使用,竟然都是采取了重写new一个,然后一个个属性字 ...

  6. java对象克隆效率_fastclone

    fastclone 一款轻量级Java对象高效克隆框架,提供高性能的深克隆(非Object->序列化->Object这种低效率克隆).浅克隆,支持递归克隆.性能上秒杀Apache Comm ...

  7. Java实现对象的克隆方式

    Java实现对象克隆的方法 1.Java实现克隆有两种形式 浅拷贝 深拷贝 在Java中吗,我们说两个对象是否相等通常有两层含义: 对象的内容是否相等,通常使用到对象的 equals(Object o ...

  8. Java的“影子克隆”和“深度克隆”

    今天来学习学习java对象的克隆,在写代码的时候,有时候我们会这样写:对象1=对象2,也就是把对象2赋值给对象1了,但是这样做有个问题,就是如果我们修改了对象2的属性值,对象1的相同属性值也被修改了, ...

  9. java中clone方法_Java Object clone()方法– Java中的克隆

    java中clone方法 Cloning is the process of creating a copy of an Object. Java Object class comes with na ...

  10. JAVA复习(对象的克隆、正则表达式)

    对象的克隆 对象的克隆就是复制的操作,和之前学习的引用传递不同 在引用传递中一个 实例 可以有多个名字 但是多个名字都指向一个对象 克隆出来的对象 和之前的对象 没有任何的引用关系 想要实现对象的克隆 ...

最新文章

  1. vst3插件_Blue Cat Audio Blue Cat PatchWork mac(蓝猫桥接插件)
  2. 基于随机梯度下降法的手写数字识别、epoch是什么、python实现
  3. 创业号官网自建系统软件 v3.1
  4. 【Hadoop 分布式部署 十 一: NameNode HA 自动故障转移】
  5. 雷军:小米MIX Alpha不是折叠屏手机,将会很震撼
  6. python将一行作为字段_Python 变量代入,指定某一行截取输出字段
  7. oracle sequence使用多,Oracle中Sequence使用的限制
  8. 薄板样条插值(Thin plate splines)的实现与使用
  9. sklearn 模型选择和评估
  10. 该弱磁算法采用单电流控制策略,额定转速以下采用MTPA控制,额定转速以上采用单电流控制
  11. selenium简单模拟百度搜索点击器
  12. android root测试,android检测是否已经具有root权限
  13. 三星手机tf卡数据恢复怎么做
  14. Report ZD600PSR028_1
  15. Android系统手机开机画面各个阶段代码执行流程分析(Part2)
  16. 2.微处理器:8088功能结构图【BIU 和 EU】 + 8088【内部各寄存器】的解释
  17. 车载、行车记录仪产品知识汇集
  18. getElementByTagName
  19. Qcom平台 Camera 之常见错误和问题
  20. 用 shell 语言提取文件中的信息到另一个文件夹中

热门文章

  1. 5 年迭代 5 次,抖音基于 Flink 的推荐系统演进历程
  2. 字节跳动单点恢复功能及 Regional CheckPoint 优化实践
  3. 视频播放器本地代理服务设计
  4. TV Metro界面(仿泰捷视频TV版)源码解析
  5. slqite3库查询数据处理方式_从数据仓库到百万标签库,精细化数据管理,这么做就够了...
  6. php中怎么引用js变量_理解下 Go 中的引用是怎么回事
  7. java http 工具类_Java发送Http请求工具类
  8. 计算机专硕超过270分人数,从18调剂看19备考策略(附76所院校19招生简章)
  9. 学生选课系统代码-2view视图层代码【MVC--v】代码
  10. 核磁谱图分析步骤_微谱技术:想要涂料开发,少不了仪器分析……