Cloning 分两类:影子克隆 shallow cloning

        深度克隆 deep cloning

* 调用 clone() 需要 implments Cloneable。此函数为 protected,如果在外部调用,需要把它重写为 public 的。Cloneable 接口本身其实是空的,也就是没有方法需要实现。所以 clone() 可以不重写。这种空的接口被称为 marker interface 标记接口 或 tagged interface 标签接口。

1. 影子克隆是简单的克隆,对于一个对象,克隆后的对象和被克隆的对象可能有相同的属性的引用。

比如:

public class Date {

    private int year;
private int month;
private int day; public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
} ************************************** public class Employee { private String name;
private int age;
private Date hireDate; public Employee (String name, int age, Date hireDate){
this.name = name;
this.age = age;
this.hireDate = hireDate;
} public static void main () {
Employee e1 = new Employee ("Jack", 32, new Date (13,2,30));
Employee e2 = (Employee) e1.clone();
}
}

这种情况下:

  • e1 == e2 为 false
  • e1.name == e2.name 为 true
  • e1.hireDate == e2.hireDate 为 true

* 所以,e1和e2虽然是不同的引用,但他们的属性 name 和 hireDate 却是同一个引用。

当修改e2时,

  • e2.age 的修改不影响 e1.age
  • e2.name 的修改不影响 e1.name ,因为 String 是 final 类,是不可变的,e2.name 的修改自动为其创建了一个新的 String。
  • e2.hireDate 的修改会影响 e1.hireDate (ex. e2.hireDate.setYear(10)),执行完此语句后,e1.hireDate 的 year 变成了 10。

这可能是我们不想看到的,对克隆的修改不应该影响本体的值。

这种情况就应该使用 深度克隆。

2. 深度克隆

深度克隆实际上就是在类中重写 clone(),使得以上的问题得以避免。

实现方法比如:

@Override
protected Object clone() throws CloneNotSupportedException {
Employee emp = (Employee) super.clone();
if (hireDate != null) // no point cloning a null object (one that does not exist)
emp.hireDate = new Date(hireDate.year, hireDate.month, hireDate.day);
return emp;
}

新建的 Date 让 e1 和 e2 的 hireDate 区分开来,互不影响了。

所以当我们想用 clone() 函数时,如果类中包含的属性有其他类的类型,一定要重写 clone()。

《Beginning Java 7》 - 2 - Cloning 克隆的更多相关文章

  1. Java提高篇——对象克隆(复制)

    假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...

  2. Java List的深度克隆

    关于java List的深度克隆 List是java容器中最常用的顺序存储数据结构之一.有些时候我们将一组数据取出放到一个List对象中,但是可能会很多处程序要读取他或者是修改他.尤其是并发处理的话, ...

  3. Java基础--对象的克隆

    文章转载自https://www.cnblogs.com/Qian123/p/5710533.html 阅读目录 为什么要克隆? 如何实现克隆 浅克隆和深克隆 解决多层克隆问题 总结 假如说你想复制一 ...

  4. java中的深浅克隆

    假设有一个对象object,在某处又需要一个跟object一样的实例object2,强调的是object和object2是两个独立的实例,只是在开始的时候,他们是具有相同状态的(属性字段的值都相同). ...

  5. java对象比较器和克隆

    一.比较器Comparable和Comparator 上一篇博客介绍了工具类Arrays工具类 .我们可以对基本类型的数组调用Arrays.sort()函数来进行数组的排序.排序操作在日常开发中经常要 ...

  6. Java学习笔记--对象克隆

    转自:Edward_qing_Lee 的专栏 http://blog.csdn.net/edward_qing_lee/article/details/8249102 一.java 方法参数 理解: ...

  7. Java 原型模式(克隆模式)

      Java 的设计模式有 23 种,前段时间小编已经介绍了单例模式,由于我们在学习 Spring 的时候在 bean 标签的学习中碰到了今天要讲的原型模式,那么小编就已本文来介绍下原型模式. 原型模 ...

  8. JAVA中对象的克隆及深拷贝和浅拷贝

    使用场景: 在日常的编程过程 中,经常会遇到,有一个对象OA,在某一时间点OA中已经包含了一些有效值 ,此时可能会需一个和OA完全相对的新对象OB,并且要在后面的操作中对OB的任何改动都不会影响到OA ...

  9. 深入浅出Java中的clone克隆方法,写得太棒了!

    作者:张纪刚 blog.csdn.net/zhangjg_blog/article/details/18369201/ Java中对象的创建 clone 顾名思义就是 复制 , 在Java语言中, c ...

随机推荐

  1. mediawiki的安装

    1. yum install httpd php pcre php-mysql php-pear php-pecl-apc mysql-server ImageMagick sendmail php- ...

  2. Elasticsearch学习系列之term和match查询实例

    Elasticsearch查询模式 一种是像传递URL参数一样去传递查询语句,被称为简单查询 GET /library/books/_search //查询index为library,type为boo ...

  3. java算法 第七届 蓝桥杯B组(题+答案) 10.压缩变换

    10.压缩变换  (程序设计) 小明最近在研究压缩算法.他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比.然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些 ...

  4. 如何了解一个Web项目

    一:学会如何读一个JavaWeb项目源代码 步骤:表结构->web.xml->mvc->db->spring ioc->log->代码 1.先了解项目数据库的表结构 ...

  5. cf499A-Watching a movie

    http://codeforces.com/problemset/problem/499/A A. Watching a movie   You have decided to watch the b ...

  6. 141. Linked List Cycle (List; Two-Pointers)

    Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using ex ...

  7. Qt5.11参考文档

    Qt5.11参考文档: http://www.bim-times.com/qt/Qt-5.11.1/qtdoc/index.html (来源于Qt官网)

  8. Opencv Canny

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  9. Ubuntu Phone开箱上手

    在昨晚举行的发布会上Canonical和硬件厂商BQ进行合作,推出了首款面向消费市场的Ubuntu手机--Aquaris E4.5,带来了与常见的iPhone和Android机完全不同的操作体验,设备 ...

  10. [Jenkins] Jenkins 执行 Composite 模式的 SoapUI Project

    cd %WORKSPACE% cmd /c call "D:\Program Files\SmartBear\ReadyAPI-1.3.1\bin\testrunner.bat" ...