Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中。那么什么是深克隆,什么是浅克隆呢。

  【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。

  【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。

  下面的两个例子可以很好的说明他们的区别:

  首先看一下类图

  Husband类有一个对wife的引用,当进行浅克隆的时,wife变量都会指向同一个Wife;而进行深克隆时,会指向不同的Wife。下面进行一下验证:

  【浅克隆】

 public Object clone() {
Husband husband = null;
try{
husband = (Husband)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}finally{
return husband;
}
}

  【深克隆】

 public Object deepClone() throws IOException,ClassNotFoundException {
//将对象写到流里
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//从流里读回来
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}

  【全部代码】

 package com.xingoo.clone;

 import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date; class Wife implements Serializable{
private String name;
private Date birthday; public Wife(){
name = "芙蓉姐姐";
birthday = new Date();
}
public Date getBirthday(){
return birthday;
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Husband implements Cloneable,Serializable{
private Wife wife;
private Date birthday; public Husband(){
wife = new Wife();
birthday = new Date();
} public Wife getWife(){
return wife;
} public Date getBirthday(){
return birthday;
}
/**
* 浅克隆一个对象
*/
public Object clone() {
Husband husband = null;
try{
husband = (Husband)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}finally{
return husband;
}
}
/**
* 利用串行化深克隆一个对象,把对象以及它的引用读到流里,在写入其他的对象
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public Object deepClone() throws IOException,ClassNotFoundException {
//将对象写到流里
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//从流里读回来
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
public class Test {
public static void main(String[] args){
try{
Husband husband = new Husband();
System.out.println("husband birthday "+husband.getBirthday().getTime());
System.out.println("wife birthday "+husband.getWife().getBirthday().getTime());
System.out.println();
Husband husband1 = (Husband)husband.clone();
System.out.println("husband1 birthday "+husband1.getBirthday().getTime());
System.out.println("wife birthday "+husband1.getWife().getBirthday().getTime());
System.out.println();
System.out.println("是否是同一个husband "+(husband == husband1));
System.out.println("是否是同一个wife "+ (husband.getWife() == husband1.getWife()));
System.out.println();
Husband husband2 = (Husband)husband.deepClone();
System.out.println("husband2 birthday "+husband2.getBirthday().getTime());
System.out.println("wife birthday "+husband2.getWife().getBirthday().getTime());
System.out.println();
System.out.println("是否是同一个husband "+(husband == husband2));
System.out.println("是否是同一个wife "+ (husband.getWife() == husband2.getWife()));
}catch(Exception e){
e.printStackTrace();
}
}
}

  【运行结果】

husband birthday
wife birthday husband1 birthday
wife birthday
是否是同一个husband false
是否是同一个wife true husband2 birthday
wife birthday
是否是同一个husband false
是否是同一个wife false

【java开发系列】—— 深克隆和浅克隆的更多相关文章

  1. Java中的深克隆和浅克隆

    为什么要克隆 首先思考一个问题, 为什么需要克隆对象? 直接new一个对象不行吗? 克隆的对象可能包含一些已经修改过的属性, 而new出来的对象的属性都还是初始化时候的值, 所以当需要一个新的对象来保 ...

  2. 浅谈Java中的深克隆和浅克隆(阿里面试)

    在最近的秋招中,阿里和多益网络都问到了这个问题,虽然很简单,但是我还是想总结一下,感兴趣的可以看一下我的个人博客网站(Spring+MyBatis+redis+nginx+mysql)(适合菜鸟),最 ...

  3. 【java开发系列】—— JDK安装

    前言 作为一个java开发者,安装JDK是不可避免的,但是配置路径却总是记不住,百度也有很多参考例子.这里仅仅当做以后参考的笔记记录. 说到JDK,就不得不提JRE.他们到底是什么呢? 通常我们进行j ...

  4. Java开发系列-文件上传

    概述 Java开发中文件上传的方式有很多,常见的有servlet3.0.common-fileUpload.框架.不管哪种方式,对于文件上传的本质是不变的. 文件上传的准备 文件上传需要客户端跟服务都 ...

  5. 【java开发系列】—— struts2简单入门示例

    前言 最近正好有时间总结一下,过去的知识历程,虽说东西都是入门级的,高手肯定是不屑一顾了,但是对于初次涉猎的小白们,还是可以提供点参考的. struts2其实就是为我们封装了servlet,简化了js ...

  6. 【java开发系列】—— 自定义注解

    之前在开发中,就总纳闷,为什么继承接口时,会出现@Override注解,有时候还会提示写注解@SuppressWarnings? 原来这是java特有的特性,注解! 那么什么是注解呢? 注解就是某种注 ...

  7. 【java开发系列】—— Tomcat编译报错

    由于之前Eclipse里面有一个可移植性的web工程,但是在我很久没用后,再次登录这个IDE的时候就发现了问题. 首先,我的电脑里面有两个版本的JDK,1.6和1.7.两个版本的Tomcat6和7以及 ...

  8. Java开发系列-JSP

    概述 JSP是java 服务器页面,它运行在服务器端,本质上就是一个serlvet,产生的java文件和class保留在tomcat的word目录下. JSP主要作用是将内容的生成与页面相分离. JS ...

  9. Java开发系列-JDBC

    概述 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和 ...

随机推荐

  1. java单元测试之Mock静态方法

    1 public final class AmountUtil { public static String CustomFormatWith2Digits(int amount) { return ...

  2. twitter storm学习 - 安装部署问题汇总

    已经碰到的或者将来碰到的关于安装部署方面的问题以及解决方法,先挖个坑 1.提交的topology在admin界面上看emitted始终都是0,查看日志发现有如下错误: worker [ERROR] E ...

  3. UI设计师与VI设计师的区别

    企业视觉形象(CorporateVisualImage)与企业视觉形象识别(VI)并不是一个概念.前者是企业与生俱来的客观存在要素,也就是说一个企业无论是否制定了它的VI,也无论其所制定的VI是否成功 ...

  4. 学习javscript函数笔记(二)

    定义: 函数包含一组语句,他们是JavaScript的基础模块单元,用于代码复用.信息隐藏和组合调用.函数用于指定对象的行为. 1.函数对象 JavaScript中的函数就是对象,函数对象连接到Fun ...

  5. 里氏替换原则(Liskov Substitution Principle) LSP

    using System; using System.Collections.Generic; using System.Text; namespace LiskovSubstitutionPrinc ...

  6. apply、call、bind区别、用法

    apply和call都是为了改变某个函数运行时的上下文而存在的(就是为了改变函数内部this的指向):   如果使用apply或call方法,那么this指向他们的第一个参数,apply的第二个参数是 ...

  7. (转)开发监控Linux 内存 Shell 脚本

    原文:http://blog.csdn.net/timchen525/article/details/76474017 题场景: 开发Shell 脚本判断系统剩余内存的大小,如果低于100MB,就邮件 ...

  8. IDEA 导入cordova3.5工程目录注意事项

    IDEA 导入cordova3.5工程目录注意事项 1 eclipse很不稳定,有很多小问题.平时我自己用idea,但是当用cordova3.5创建好工程目录是,用eclipse导入时没有问题的.但是 ...

  9. 【坑】自动化测试之Excel表格

    参考一位大神的博客项目架构,把元素和数据都参数化,但是总是被excel表格坑 1.无法下拉 动作列通过下拉列表来控制,点击下拉列表无反应 解决方案:不知道是不是中间动了什么,因为Excel版本的问题, ...

  10. ASP.NET之Request和Response对象

    经过了牛腩新闻公布系统和html的学习对B/S开发的流程有了些理解.前面尽管用到了非常多知识.但对制作网页仅仅能说知其然.当学到asp.net视频中的解说才干够说開始知其所以然了. 今天来说说clie ...