`
EricDanniel
  • 浏览: 16398 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

对象的克隆

阅读更多

为什么需要克隆:

在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,AB是两个独立的对象,但B的初始值是由A对象确定的。在Java语言中,用简单的赋值语句是不能满足这种需求的,要满足这种需求有很多途径。

 

克隆的实现方式

一、浅度克隆

对于要克隆的对象,对于其基本数据类型的属性,复制一份给新产生的对象,对于非基本数据类型的属性,仅仅复制一份引用给新产生的对象,即新产生的对象和原始对象中的非基本数据类型的属性都指向的是同一个对象

1、实现java.lang.Cloneable接口

clone的类为什么还要实现Cloneable接口呢?Cloneable接口是一个标识接口,不包含任何方法的!这个标识仅仅是针对Object类中clone()方法的,如果clone类没有实现Cloneable接口,并调用了Object clone()方法(也就是调用了super.Clone()方法),那么Objectclone()方法就会抛出 CloneNotSupportedException异常。

 

2、重载java.lang.Object.clone()方法

JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。

 

观察一下Object类的clone()方法是一个native方法,native方法的效率一般来说都是远高于java中的非native方法。这也解释了为什么要用Objectclone()方法而不是先new一个类,然后把原始对象中的信息赋到新对象中,虽然这也实现了clone功能。Object类中的clone()还是一个protected属性的方法,重载之后要把clone()方法的属性设置为public

 

Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。

 

public class Product implements Cloneable {
	private String name;

	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			return null;
		}
	}
}

 

 

 

二、深度克隆

在浅度克隆的基础上,对于要克隆的对象中的非基本数据类型的属性对应的类,也实现克隆,这样对于非基本数据类型的属性,复制的不是一份引用,即新产生的对象和原始对象中的非基本数据类型的属性指向的不是同一个对象

 

要克隆的类和类中所有非基本数据类型的属性对应的类

1、都实现java.lang.Cloneable接口

 

2、都重载java.lang.Object.clone()方法

 

public class Attribute implements Cloneable {
	private String no;
	
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			return null;
		}
	}
}

public class Product implements Cloneable {
	private String name;
	
	private Attribute attribute;

	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			return null;
		}
	}
}

  

 

 

三、使用对象序列化和反序列化实现深度克隆

所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象。

 

对象的序列化还有另一个容易被大家忽略的功能就是对象复制(Clone),Java中通过Clone机制可以复制大部分的对象,但是众所周知,Clone有深度Clone和浅度Clone,如果你的对象非常非常复杂,并且想实现深层 Clone,如果使用序列化,不会超过10行代码就可以解决。

 

虽然Java的序列化非常简单、强大,但是要用好,还有很多地方需要注意。比如曾经序列化了一个对象,可由于某种原因,该类做了一点点改动,然后重新被编译,那么这时反序列化刚才的对象,将会出现异常。 你可以通过添加serialVersionUID属性来解决这个问题。如果你的类是个单例(Singleton)类,是否允许用户通过序列化机制复制该类,如果不允许你需要谨慎对待该类的实现。

 

public class Attribute {
	private String no;
}

public class Product {
	private String name;
	
	private Attribute attribute;

	public Product clone() {
		ByteArrayOutputStream byteOut = null;
		ObjectOutputStream objOut = null;
		ByteArrayInputStream byteIn = null;
		ObjectInputStream objIn = null;
		
		try {
			byteOut = new ByteArrayOutputStream(); 
			objOut = new ObjectOutputStream(byteOut); 
			objOut.writeObject(prototype);

			byteIn = new ByteArrayInputStream(byteOut.toByteArray());
			objIn = new ObjectInputStream(byteIn);
			
			return (ContretePrototype) objIn.readObject();
		} catch (IOException e) {
            throw new RuntimeException("Clone Object failed in IO.",e);   
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Class not found.",e);   
        } finally{
            try{
            	byteIn = null;
                byteOut = null;
                if(objOut != null) objOut.close();   
                if(objIn != null) objIn.close();   
            }catch(IOException e){   
            }   
        }
	}
}

  

 

 

分享到:
评论

相关推荐

    JAVA_对象克隆

    在Java编程语言中,对象克隆是一种创建与现有对象具有相同数据的新对象的过程。这个过程在需要复制对象的所有属性而不创建新类型实例时非常有用。本文将深入探讨Java中的对象克隆,包括其原理、实现方式以及注意事项...

    对象克隆技术笔记

    031111_【第11章:Java常用类库】_对象克隆技术笔记

    对象克隆(clone)详解.docx

    【对象克隆(clone)详解】 对象克隆是Java编程中的一个重要概念,它允许我们创建一个已有对象的副本,而不影响原始对象。在Java中,克隆主要涉及到`Object`类中的`clone()`方法,以及两种不同的克隆类型:浅克隆和...

    java 对象克隆

    在Java编程语言中,对象克隆是一种创建一个与原对象具有相同数据的新对象的过程。对象克隆主要用于复制或备份对象,以便在不干扰原始对象的情况下对其进行修改或操作。本篇文章将详细探讨Java中的对象克隆及其实现...

    Java编程实现对象克隆(复制)代码详解

    Java编程实现对象克隆(复制)代码详解 在 Java 编程中,对象克隆是一种非常重要的技术,它允许开发者创建一个对象的副本,具有相同的属性和行为。对象克隆可以分为浅克隆和深克隆,浅克隆仅复制对象的引用,而深...

    clone()方法示例(对象克隆)_对象克隆_nervouse78_源码

    1. **实现Cloneable接口**:`Cloneable`接口在Java中是一个标记接口,表示该类的对象可以被克隆。虽然它没有定义任何方法,但实现这个接口是调用`clone()`的前提。 2. **重写`clone()`方法**:默认的`clone()`方法...

    计算机前端-核心编程.视频07对象克隆.avi

    计算机前端-核心编程.视频07对象克隆.avi

    对象克隆、复制工具

    对象复制工具,基于cglib BeanCopier 实现对实体对象、持久化对象、代理对象的克隆和复制, 避免重复克隆和复制,避免无限循环引用,(校验hashCode) 可指定实体对象和集合属性的克隆深度

    Java对象的复制克隆

    Java中的对象复制与克隆是程序开发中常见的需求,主要用于创建一个对象的副本,而不会影响原始对象的状态。这里主要讨论两种类型的对象拷贝:浅拷贝和深拷贝。 浅拷贝,也称为表面拷贝,是创建一个新的对象,然后将...

    如何进行Java对象的克隆.pdf

    "Java 对象克隆详解" Java 对象克隆是 Java 编程中一个重要的概念。由于 Java 中的对象使用引用类型,所以没有直接的方法可以将对象的内容复制到一个新的对象。Java 提供了一个特殊的 clone() 方法,为所有的引用...

    php实现对象克隆的方法

    PHP实现对象克隆的知识点主要涉及对象的深拷贝与浅拷贝的概念、PHP对象克隆的语法以及__clone魔术方法的使用。以下为详细知识点: 1. 对象克隆基本概念: 对象克隆,是面向对象编程中的一项技术,用于创建一个与...

    PHP对象克隆clone用法示例

    对象克隆通常用于需要复制对象属性或方法的状态时,以保证原始对象的独立性。在PHP中,对象的克隆可以通过使用`clone`关键字实现,而PHP的对象克隆分为浅克隆和深克隆两种。 浅克隆只是复制对象中的非对象和非资源...

    java克隆对象(两种方法)

    java的两种深度克隆方法,1cloneTest是用Cloneable接口的clone方法实现(对象必须要实现cloneable接口).2cloneSerialize.java是用对象流写对象到byte数组中,然后从byte数组中取得对象.(对象必须要实现serializble接口)

    PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析

    在讨论对象克隆时,还需要提到魔术方法`__clone()`,它在对象被克隆时自动调用,允许我们在克隆过程中对新对象进行自定义初始化。 1. **对象克隆**: 当使用`clone`关键字时,PHP会创建一个现有对象的新实例,这个...

    java 深克隆浅克隆

    在Java编程语言中,克隆是一种创建对象副本的方法,它允许我们复制一个对象并拥有一个完全独立的新实例,而不是仅仅引用原始对象。克隆技术在处理复杂数据结构、避免对象共享以及实现对象复制等方面有着广泛的应用。...

    (源码下载)jdk6.0从入门到精通-----chapter2--输入输出,克隆对象

    标题 "(源码下载)jdk6.0从入门到精通-----chapter2--输入输出,克隆对象" 提供了我们要探讨的主题,即Java中的输入输出流(I/O Stream)和对象克隆。在这个章节中,我们将深入理解这两个关键概念。 **输入输出流...

    clone 深度克隆对象

    深度克隆,也称为完全克隆,是一种创建新对象的技术,这个新对象不仅包含原始对象的所有属性值,还包含了嵌套对象的完整副本。这意味着如果一个对象中包含了其他对象的引用,深度克隆会创建这些引用对象的独立副本,...

Global site tag (gtag.js) - Google Analytics