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

java的clone机制

阅读更多
首先了解下,什么叫作clone,以及深拷贝和浅拷贝的区别?
对象clone机制,是指根据源对象clone一个对象,这个clone对象与原来的对象相互隔离,但是内容相同。
即:
source != source.clone();
source.getClass()=source.clone().getClass();
source.equalWith(source.clone());
浅拷贝:浅拷贝是指对象的引用类型成员变量拷贝的只是变量所存的内存地址,而不是引用类型成员变量所指内存的内容。即拷贝对象与原对象引用类型成员变量指向同一个内存。
a为原对象,b是拷贝对象

深拷贝:是不仅基本数据类型被拷贝,引用类型的成员变量拷贝的是变量所指内存。使得拷贝对象和原对象的引用类型成员变量也相互隔离开,做到了拷贝对象与原对象完全的隔离。
a为原对象,b是拷贝对象


然后我们来讲讲,了解下java自带的clone机制——浅拷贝
java的object对象有一个clone方法,它的具体实现是由native方法实现的,效率较高。它是一个浅拷贝。
package clonetest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public final class Acount implements Cloneable{
	private int i;
	private String words = "haha";
	private User user;
	public Acount(int i,User user){
		this.i = i;
		this.user = user;
	}
	/*@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		Acount copy = (Acount) super.clone();
		if(user!=null){
			copy.user = (User) user.clone();
		}
		return copy;
	}*/
	public static Object copy(Object o) throws IOException, ClassNotFoundException{
		ByteArrayOutputStream bs = new ByteArrayOutputStream();
		ObjectOutputStream os = new ObjectOutputStream(bs);
		os.writeObject(o);
		os.flush();
		ByteArrayInputStream is = new ByteArrayInputStream(bs.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(is);
		return ois.readObject();
		
	}
	public static void main(String args[]){
		try {
			User user = new User("zbq",22);
			Acount source = new Acount(0,user);
			Acount clone = (Acount)(source.clone());
			System.out.println("source==clone:"+(source==clone));
			System.out.println("source.i==clone.i:"+(source.i==clone.i));
			source.i=1;
			System.out.println("after change,source.i==clone.i:"+(source.i==clone.i));
			System.out.println("source.words==clone.words:"+(source.words==clone.words));
			source.words="byebye";
			System.out.println("after change,source.words==clone.words:"+(source.words==clone.words));
			System.out.println("source.user==clone.user:"+(source.user==clone.user));
			source.user.name = "lxl";
			System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
			System.out.println(clone.user.name);
			source.user = new User("",1);
			System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	static class User implements Cloneable{
		private String name;
		private int age;
		public User(String name,int age){
			this.name = name;
			this.age = age;
		}
		@Override
		protected Object clone() throws CloneNotSupportedException {
			// TODO Auto-generated method stub
			return super.clone();
		}
		
	}
	
}

实现clone的步骤
1 声明实现Cloneable接口。
2 调用super.clone拿到一个对象,如果父类的clone实现没有问题的话,在该对象的内存存储中,所有父类定义的field都已经clone好了,该类中的primitive和不可变类型引用也克隆好了,可变类型引用都是浅copy。
3 把浅copy的引用指向原型对象新的克隆体。

自己来实现深拷贝
package clonetest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public final class Acount implements Cloneable{
	private int i;
	private String words = "haha";
	private User user;
	public Acount(int i,User user){
		this.i = i;
		this.user = user;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		Acount copy = (Acount) super.clone();
		if(user!=null){
			copy.user = (User) user.clone();
		}
		return copy;
	}
	public static Object copy(Object o) throws IOException, ClassNotFoundException{
		ByteArrayOutputStream bs = new ByteArrayOutputStream();
		ObjectOutputStream os = new ObjectOutputStream(bs);
		os.writeObject(o);
		os.flush();
		ByteArrayInputStream is = new ByteArrayInputStream(bs.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(is);
		return ois.readObject();
		
	}
	public static void main(String args[]){
		try {
			User user = new User("zbq",22);
			Acount source = new Acount(0,user);
			Acount clone = (Acount)(source.clone());
			System.out.println("source==clone:"+(source==clone));
			System.out.println("source.i==clone.i:"+(source.i==clone.i));
			source.i=1;
			System.out.println("after change,source.i==clone.i:"+(source.i==clone.i));
			System.out.println("source.words==clone.words:"+(source.words==clone.words));
			source.words="byebye";
			System.out.println("after change,source.words==clone.words:"+(source.words==clone.words));
			System.out.println("source.user==clone.user:"+(source.user==clone.user));
			source.user.name = "lxl";
			System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
			System.out.println(clone.user.name);
			source.user = new User("",1);
			System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	static class User implements Cloneable{
		private String name;
		private int age;
		public User(String name,int age){
			this.name = name;
			this.age = age;
		}
		@Override
		protected Object clone() throws CloneNotSupportedException {
			// TODO Auto-generated method stub
			return super.clone();
		}
		
	}
	
}

使用Serializable方式来实现深拷贝
前提是相关类必须都实现Serializable接口,且可能因为版本更换,老版本的序列化对象无法反序列化。
	
public static Object copy(Object o) throws IOException, ClassNotFoundException{
		ByteArrayOutputStream bs = new ByteArrayOutputStream();
		ObjectOutputStream os = new ObjectOutputStream(bs);
		os.writeObject(o);
		os.flush();
		os.close();
		ByteArrayInputStream is = new ByteArrayInputStream(bs.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(is);
		Object o1 = ois.readObject();
		ois.close();
		is.close();
		bs.close();
		return o1;
	}
分享到:
评论

相关推荐

    Java中的克隆(Clone)机制

    现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过一阵子,在java中也有这么一个概念,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的...

    java Clone

    总之,Java的`clone`机制提供了复制对象的能力,通过实现`Cloneable`接口和覆盖`clone`方法,我们可以创建对象的副本,同时保证原对象不受影响。根据需求的不同,可以选择浅克隆或深克隆来处理对象及其引用的复杂性...

    Java性能优化技巧集锦.pdf

    1. Java clone机制和工厂模式的应用(1.1节): - clone()方法的重写和使用。 - 工厂方法设计模式在创建对象时的应用,以达到解耦合和提高代码复用的目的。 - 利用clone()方法进行对象深拷贝和浅拷贝的区别和实现...

    Java Clone(类的复制)实例代码

    在Java编程语言中,`Clone`机制是一种对象复制的方式,允许创建一个现有对象的副本。在Java中,对象的默认复制是浅复制(shallow copy),这意味着只复制对象本身,而不复制它引用的对象。要实现深复制(deep copy)...

    Java clone方法详解及简单实例

    Java中的`clone`方法是Java语言提供的一种复制对象的机制,它允许创建一个现有对象的副本,这个副本具有与原始对象相同的状态,但它们是独立的实体,对其中一个对象的修改不会影响另一个。`clone`方法是Java `Object...

    Java Clone深拷贝与浅拷贝的两种实现方法

    Java Clone 是 Java 语言中的一种复制对象的机制,它可以将一个对象的所有属性和状态复制到另一个对象中,实现对象的深拷贝和浅拷贝。下面我们将讨论 Java 中的深拷贝和浅拷贝的两种实现方法。 一、浅拷贝 浅拷贝...

    java中的指针,引用及对象的clone

    本文将深入探讨Java中的引用以及对象的克隆机制,包括浅拷贝和深拷贝的区别及其应用场景。 #### 二、Java中的引用 在Java中,当使用`new`关键字创建一个对象时,实际上创建的是一个指向该对象的引用。例如,以下...

    Java中的clone方法详解_动力节点Java学院整理

    下面我们将详细介绍Java中的clone方法,并讨论它的实现机制和应用场景。 什么是clone方法 clone方法顾名思义,就是复制,在Java语言中,clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源...

    如何通过JVM角度谈谈Java的clone操作

    首先,让我们理解`clone`方法的工作机制。在Java中,`clone`方法是`Object`类的一个受保护的方法,这意味着所有Java对象都隐含地继承了这个方法。然而,`Object`类的`clone()`方法执行的是浅克隆,即如果对象包含...

    浅析Java中clone()方法浅克隆与深度克隆

    Java中的克隆(Clone)机制是面向对象编程中一种创建对象副本的方法,它允许程序员创建一个已有对象的新实例,新实例的数据与原对象相同。在Java中,克隆分为两种类型:浅克隆(Shallow Clone)和深度克隆(Deep ...

    JAVA_高级特性(hashCode,clone,比较器,Class反射,序列化)

    ### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。

    Clone详解.doc

    Java中的克隆(Clone)机制是一种创建对象副本的方法,它允许程序员复制一个对象的状态,而不会影响原始对象。克隆在编程中常用于创建对象的独立副本,使得新副本与原对象之间相互独立,对其中一个对象的修改不会...

    java-6个机制.doc

    Java的克隆机制通过`Object.clone()`方法实现,该方法位于`java.lang.Object`类中。 **1.2 实现要求** - **实现`Cloneable`接口**:被克隆的类必须实现`Cloneable`接口,表明该类支持克隆操作。 - **重写`clone()`...

    (完整word版)java6个机制.doc

    Java 语言中的六个核心机制包括克隆、序列化、多线程、异常处理、垃圾回收以及反射。在这里,我们将详细探讨前三个机制。 首先,让我们来看看克隆机制。克隆在编程中指的是复制一个对象并在内存中创建其副本。在 ...

Global site tag (gtag.js) - Google Analytics