`
langlanglanglang
  • 浏览: 31536 次
  • 性别: 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)是Java语言的特性之一,本篇文章主要介绍了Java中的Clone机制是如何工作的,需要的朋友可以参考下

    Clone详解.doc

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

    J2SE笔记讲解个人修订(1.1).docx

    1 JAVA认识 2 JAVA数据类型 3 面向对象程序设计 4 JAVA集合 5 JAVA反射机制 6 JAVA注解(ANNOTATION) 7 JAVA中的异常类 ...20 JAVA克隆CLONE(复制) 21 JAVA 网络编程 22 JAVA 其他未归类 23 JNI概述

    java面试题.pdf

    3. Java中垃圾回收的机制是什么? 4. Java中什么是反射? 5. Java中什么是线程安全? 6. Java中抽象类和接口的区别是什么? 7. Java中什么是异常? 8. Java中如何防止对象的clone? 9. Java中什么是泛型? 10. Java...

    java语言程序设计 java编程笔记 由浅入深的笔记 共32份 全套资源.rar

    clone.docx Date日期.docx GC垃圾回收机制.docx instanceof运算符.docx io.docx java基础关键字.docx java命名和数据类型.docx java序列化.docx Math类.docx Object(对象).docx operator(运算符).docx ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    Java面试宝典2017.zip

    23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static Nested ...

    java面试宝典

    46、java 中实现多态的机制是什么? 12 47、在java 中一个类被声明为final 类型,表示了什么意思? 12 48、下面哪些类可以被继承? 12 49、指出下面程序的运行结果: 【基础】 13 52、关于内部类: 13 53、数据类型...

    Java面试宝典-经典

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

    java 面试题 总结

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...

    Java面试宝典2010版

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

    java面试题大全(2012版)

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

    java 面试常问的问题 如何回答

    一. Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。...43、Java中的异常处理机制的简单原理和应用。 28 等等........

    Java的反射中一些重要的方法

     Java中有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode、equals、clone、toString、getClass等。其中getClass返回一个Class 对象。Class对象十分特殊。他是...

    基于JAVA的搜索引擎 lucene-2.2.0

    rollbackSegmentInfos = (SegmentInfos) segmentInfos.clone(); // 克隆 } // 默认的删除策略实现类为KeepOnlyLastCommitDeletionPolicy,它只是保证将最近提交删除的索引文件,提交删除动作 // ...

    Java核心技术II(第8版)

    10.4.5 远程对象与equals、hashCode和clone方法 10.5 远程对象激活 10.6 Web Services与JAX-WS 10.6.1 使用JAX-WS 10.6.2 Web服务的客户端 10.6.3 Amazon的E-Commerce服务 第十一章 脚本、编译与注解处理 11.1 Java...

    深入理解java中的拷贝机制

    主要给大家深入介绍了java中的拷贝机制,网上关于java中拷贝的文章也很多,但觉得有必要再深的介绍下java的拷贝机制,有需要的朋友可以参考学习,下面来一起看看吧。

Global site tag (gtag.js) - Google Analytics