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

这里面涉及到两个类,一个是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对象,其实只是把对象的引用复制一份过去给另外的对象,对象是没有做出任何改变

时间: 2024-09-30 11:05:06

java基础入门-对象的浅克隆与深克隆的相关文章

java基础入门-对象流与序列化

概念 对象序列化:将对象输入到流里面,并在之后将其读回. 注意事项 对象需要实现Serializable接口,Serializable接口没有任何方法,不需要重写 由于对象可能会重复使用,对象暂用不再是原来的内存地址,因此,序列化过程中引入序列号这个东西,如下图 序列化用途 对象通过序列化,然后在网络中传输,不同的机器负责不同的计算部分,从而实现分布式计算,提高计算的效率 版权声明:本文为博主原创文章,未经博主允许不得转载.

Java基础学习 —— 对象的克隆

对象的克隆分为对象的浅克隆和深克隆 一.对象的浅克隆 注意事项: 1.如果一个对象需要调用clone的方法克隆,那么该对象必须要实现Cloneable接口 2.Cloneable对象只是一个标识对象,并没有方法 1 public class demo1 { 2 public static void main(String[] args) throws Exception { 3 Person person = new Person("001","狗娃"); 4 Pe

Java基础入门 传智播客pdf

下载地址:网盘下载 内容简介 <Java基础入门>从初学者的角度详细讲解了Java开发中重点用到的多种技术.全书共11章,包括Java开发环境的搭建及其运行机制.基本语法.面向对象的思想,采用典型翔实的例子.通俗易懂的语言阐述面向对象中的抽象概念.在多线程.常用API.集合.IO.GUI.网络编程章节中,通过剖析案例.分析代码结构含义.解决常见问题等方式,帮助初学者培养良好的编程习惯.最后,讲解了Eclipse开发工具,帮助初学者熟悉开发工具的使用.  <Java基础入门>附有配套

Java基础入门 目录:

本系列博文内容主要是自己日常工作学习中常见.注意.以及还需要巩固的内容,有些本人熟练掌握的内容不在该博文内,也不能当作查询技术的"海词"使用,主要用于学习并记录成长!!! Java开发入门 Java编程基础 Java API

JAVA基础入门通关检测

一.JAVA基础知识点问答(1.2.3章) 1. JDK1.6.0_06软件的安装.(请安装在 C:\Java 目录下) 2. JAVA的开发环境如何配置?(即:JAVA_HOME . Path . CLASSPATH 的配置) 3. 开发一个JAVA应用程序的步骤是?(如下程序) public class FirstSample { public static void main(String[] args ) { System.out.print ("欢迎你们来北京,来到"); S

java基础知识-对象和类

前言: 因为要准备Java面试,所有将java基础知识点重新复习一遍,主要笔记来源于菜鸟教程和java核心技术的书籍中,也有一些博客上的资料(这些只供我个人学习使用) Java 对象和类 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有:摇尾巴.叫.吃等. 类:类是一个模板,它描述一类对象的行为和状态. 下图中男孩女孩为类,而具体的每个人为该类的对象: 1.Java中的对象 现在让我们深入了解什么是对象.看看周围真实的世界,会发现身边有很多对象

Java 基础入门

Java基础 JVM.JDK.JRE三者的关系: JDK:(Java Develop Kit)主要是针对开发人员使用的,是整个java的核心.它包括了Java运行环境(JRE),Java工具( javac/java/jdb等 )和Java基础类库. JRE:(Java Runtime Environment)是运行java程序必须的环境的集合.它包括了JVM标准实现和Java核心类库. JVM:(Java Virtual Machine)java虚拟机,java本身不跨平台,java跨平台是依靠

Java基础入门(十一)之基本数据包装类以及简单转换

一.   基本数据类型包装类 引用数据类型一般为基本数据类型首字母大写,除了int .char,其中int的引用数据类型类Integer,char的引用数据类型为Character 关系: 基本数据类型之间的关系 互相兼容 基本数据类型对应的包装类 不存在任何关系 3.基本数据类型 和 基本数据类型包装类之间的转换 3.1装箱:将基本数据类型 封装成对应的包装类类型 语法: jdk>1.5 自动装箱 包装类型 对象的引用 = 基本数据类型; 默认调用了static Integer valueOf

Java对象的浅克隆和深克隆

为什么需要克隆 在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B, 并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的.在Java语言中,用简单的赋值语句是不 能满足这种需求的,要满足这种需求有很多途径.     克隆的实现方式   一.浅度克隆      浅度克隆对于要克隆的对象,对于其基本数据类型的属性,复制一份给新产生的对象,对于非基本数据类型的属性,仅仅