文档章节

java基础入门-对象的浅克隆与深克隆

raylee2015
 raylee2015
发布于 2015/08/24 14:40
字数 950
阅读 5
收藏 0

这里面涉及到两个类,一个是person类,一个是测试类test


首先我们说到的是浅克隆,对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,如果是基本数据类型(int,float,char等)到没什么问题,基本遇上如string,Integer等不可变对象的时候也没有什么问题,但是如果遇上了date这个可变对象,或者是自己定义的可变对象,他只是简单的复制一下引用这些可变对象,而不是把这些可变对象再一次的复制


先上person类,这里面虽然是实现Cloneable接口,但是里面没有重写方法,只是super了一下就算了


package com.ray.object;

import java.util.Date;

/**
 * 人
 * 
 * @author ray
 * @since 2015-05-07
 * @version 1.0
 * 
 */
public class Person implements Cloneable {

	private int id = 0;
	private String name = "";
	private Date birthday = null;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	protected Object clone() {
		Object obj = null;
		try {
			obj = super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}

}


再上测试类

package com.ray.object;

import java.util.Date;

/**
 * 浅克隆和深克隆
 * 
 * @author ray
 * @since 2015-05-07
 * @version 1.0
 * 
 */
public class Test {

	public static void main(String[] args) {
		Person bill = new Person();
		bill.setId(1);
		bill.setName("bill");
		bill.setBirthday(new Date());
		System.out.println("bill.getId() --- "+bill.getId());
		System.out.println("bill.getName() --- "+bill.getName());
		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
		Person jack = (Person) bill.clone();
		System.out.println("jack.getId() --- "+jack.getId());
		System.out.println("jack.getName() --- "+jack.getName());
		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Date jacksBirthday = jack.getBirthday();
		jacksBirthday.setTime(System.currentTimeMillis());
		System.out.println("bill.getId() --- "+bill.getId());
		System.out.println("bill.getName() --- "+bill.getName());
		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
		System.out.println("jack.getId() --- "+jack.getId());
		System.out.println("jack.getName() --- "+jack.getName());
		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
	}
}


输出:

bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 08:56:33 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 08:56:33 CST 2015
bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 08:56:35 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 08:56:35 CST 2015




由上面可以看见,基本jack这个对象是clone了bill这个对象,但是这里面只是简单复制一下引用,当我们修改jack对象里面的生日时,bill的生日竟然也跟着变了



下面,我们再说一下深克隆,就是把对象的所有域全部复制一份


先上Person类,这次Person类重写了clone方法,除了super之外,还把里面的birthday属性也复制一份


package com.ray.object;

import java.util.Date;

/**
 * 人
 * 
 * @author ray
 * @since 2015-05-07
 * @version 1.0
 * 
 */
public class Person implements Cloneable {

	private int id = 0;
	private String name = "";
	private Date birthday = null;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	protected Object clone() {
		Object obj = null;
		try {
			obj = super.clone();
                        //下面把生日也复制一份
			Person person = (Person) obj;
			person.birthday = (Date) birthday.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}

}

再上Test类,其实Test类没有做任何的改动,这里只是为了阅读方便,也写上了


package com.ray.object;

import java.util.Date;

/**
 * 浅克隆和深克隆
 * 
 * @author ray
 * @since 2015-05-07
 * @version 1.0
 * 
 */
public class Test {

	public static void main(String[] args) {
		Person bill = new Person();
		bill.setId(1);
		bill.setName("bill");
		bill.setBirthday(new Date());
		System.out.println("bill.getId() --- "+bill.getId());
		System.out.println("bill.getName() --- "+bill.getName());
		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
		Person jack = (Person) bill.clone();
		System.out.println("jack.getId() --- "+jack.getId());
		System.out.println("jack.getName() --- "+jack.getName());
		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Date jacksBirthday = jack.getBirthday();
		jacksBirthday.setTime(System.currentTimeMillis());
		System.out.println("bill.getId() --- "+bill.getId());
		System.out.println("bill.getName() --- "+bill.getName());
		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
		System.out.println("jack.getId() --- "+jack.getId());
		System.out.println("jack.getName() --- "+jack.getName());
		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
	}
}



输出:

bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 09:22:03 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 09:22:03 CST 2015
bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 09:22:03 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 09:22:05 CST 2015




由上面的输出可以看到,jack里面birthday的改动不再影响bill里面的birthday



最后,我们来说一下使用=来copy对象,其实只是把对象的引用复制一份过去给另外的对象,对象是没有做出任何改变

版权声明:本文为博主原创文章,未经博主允许不得转载。

© 著作权归作者所有

raylee2015
粉丝 6
博文 265
码字总数 44224
作品 0
江门
私信 提问
Java拾遗:008 - 对象克隆与浅拷贝、深拷贝

对象克隆 Object类中有一个方法叫,完整代码 首先它是一个Native方法,而且是受保护的(),抛出一个异常(JDK1.8)。 通常程序员自己定义的类不能直接调用方法,如果要在外部调用,需要重写...

一别丶经年
2018/08/04
48
0
Java中如何克隆集合——ArrayList和HashSet深拷贝

编程人员经常误用各个集合类提供的拷贝构造函数作为克隆,,,或者其他集合实现的方法。需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味着存储在原始List和克隆List中...

markGao
2014/04/18
1K
0
Java中如何克隆集合——ArrayList和HashSet深拷贝

编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法。需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味着存...

LCZ777
2014/04/14
68
0
Java中的克隆Cloneable

浅克隆与深克隆 当拷贝一个变量时,原始变量与拷贝变量引用了同一个对象。那么当改变一个变量所引用的对象时,就会对另一个变量产生影响。形象化一点说,就像某人A有一把遥控,用来控制电视,...

静水楼台
2013/06/04
218
0
深入理解原型模式 ——通过复制生成实例

Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide一 原型模式介绍 在面向对象系统中,使用原型模式来复制一个对象自...

Amsour丶
2018/06/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于ThinkPHP5.1+的Log无法记录SQL调试记录的小经历

项目开发阶段,除了基本编码外,性能也需要实时关注与优化。之前我的大部分项目都是使用ThinkPHP5.0以及ThinkPHP3.2,对于框架提供的日志记录和日志配置都差不多,然后使用ThinkPHP5.1的时候...

北桥苏
37分钟前
2
0
TiDB Binlog 源码阅读系列文章(四)Pump server 介绍

作者: satoru 在 上篇文章 中,我们介绍了 TiDB 如何通过 Pump client 将 binlog 发往 Pump,本文将继续介绍 Pump server 的实现,对应的源码主要集中在 TiDB Binlog 仓库的 pump/server.go...

TiDB
41分钟前
2
0
OSChina 周五乱弹 ——不知道假装开心,装的像么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :天黑了 你很忧愁, 你说世界上, 找不到四块五的妞, 行走在凌晨两点的马路上, 你疲倦地拿着半盒黄鹤楼。#今日歌曲推荐# 《四块...

小小编辑
今天
2.5K
19
Windows下学习C语言有哪些集成开发软件?

前言 初学者学习C语言遇到的最大困难想必就是搭建环境了,相当多的初学者就是被搭建环境导致放弃了学习编程,就我自己的经验而言,初学编程不应该受限于环境,使用成熟好用的环境就可以了,之...

Allen5G
昨天
3
0
Hello,Servlet!

Servlet来源 上文说过了servlet是什么,我们从servlet是什么中也可以了解到servlet的来源:servlet是Java的一个类,并且能够运行在web容器上,所以servlet是按照web容器的规范和Java的规范写...

蒙尘
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部