zoukankan      html  css  js  c++  java
  • 原型设计模式及深拷贝

    public class DeepProtoType implements Serializable, Cloneable{
    	
    	public String name; //String 属性
    	public DeepCloneableTarget deepCloneableTarget;// 引用类型
    	public DeepProtoType() {
    		super();
    	}
    	
    	
    	//深拷贝 - 方式 1 使用clone 方法
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		
    		Object deep = null;
    		//这里完成对基本数据类型(属性)和String的克隆
    		deep = super.clone(); 
    		//对引用类型的属性,进行单独处理
    		DeepProtoType deepProtoType = (DeepProtoType)deep;
    		deepProtoType.deepCloneableTarget  = (DeepCloneableTarget)deepCloneableTarget.clone();
    		
    		// TODO Auto-generated method stub
    		return deepProtoType;
    	}
    	
    	//深拷贝 - 方式2 通过对象的序列化实现 (推荐)
    	
    	public Object deepClone() {
    		
    		//创建流对象
    		ByteArrayOutputStream bos = null;
    		ObjectOutputStream oos = null;
    		ByteArrayInputStream bis = null;
    		ObjectInputStream ois = null;
    		
    		try {
    			
    			//序列化
    			bos = new ByteArrayOutputStream();
    			oos = new ObjectOutputStream(bos);
    			oos.writeObject(this); //当前这个对象以对象流的方式输出
    			
    			//反序列化
    			bis = new ByteArrayInputStream(bos.toByteArray());
    			ois = new ObjectInputStream(bis);
    			DeepProtoType copyObj = (DeepProtoType)ois.readObject();
    			
    			return copyObj;
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    			return null;
    		} finally {
    			//关闭流
    			try {
    				bos.close();
    				oos.close();
    				bis.close();
    				ois.close();
    			} catch (Exception e2) {
    				// TODO: handle exception
    				System.out.println(e2.getMessage());
    			}
    		}
    		
    	}
    	
    }
    
    
    public class DeepCloneableTarget implements Serializable, Cloneable {
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    
    	private String cloneName;
    
    	private String cloneClass;
    
    	//构造器
    	public DeepCloneableTarget(String cloneName, String cloneClass) {
    		this.cloneName = cloneName;
    		this.cloneClass = cloneClass;
    	}
    
    	//因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		return super.clone();
    	}
    }
    
    
    public class Client {
    
    	public static void main(String[] args) throws Exception {
    		// TODO Auto-generated method stub
    		DeepProtoType p = new DeepProtoType();
    		p.name = "宋江";
    		p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");
    		
    		//方式1 完成深拷贝
    		
    //		DeepProtoType p2 = (DeepProtoType) p.clone();
    //		
    //		System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
    //		System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
    	
    		//方式2 完成深拷贝
    		DeepProtoType p2 = (DeepProtoType) p.deepClone();
    		
    		System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
    		System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
    	
    	}
    
    }
    
    
    p.name=宋江p.deepCloneableTarget=1028566121
    p2.name=宋江p2.deepCloneableTarget=558638686
    

    总结:

    原型设计模式:用原型实例指定创建对象的种类, 并且通过拷贝这些原型创建新的对象。

    注意:

    1. java中只有值传递,如果是引用类型,传递的是引用,其实也是值传递。
    2. 原型设计模式有深拷贝和浅拷贝,通过Object类的Clone()方法,要使用该方法,必须实现Cloneable接口,想要clone 的属性,不能是final的。
    3. 使用序列化的方式实现深拷贝,必须实现Serializable接口
    4. 值得一提的是,本例中的深拷贝,即DeepCloneableTarget中的两个类型为string类型,拷贝的其实也是引用,但是string类型比较特殊,String类型是不可变的,值存于常量池中,所以我们克隆了两个Sheep时,修改其属性的属性cloneName时,并不会对另一个造成影响。
    5. 使用序列化进行拷贝时,由于是二进制的拷贝,所有构造函数不会被执行。这也是优点,也是缺点,在实际应用中要考虑
    你所看得到的天才不过是在你看不到的时候还在努力罢了!
  • 相关阅读:
    微信公众号教程(5)自动回复操作案例
    微信公众号教程(4)微信公众平台编辑模式介绍
    微信公众号教程(3)微信公众平台群发消息
    微信公众号教程(2)微信公众平台后台介绍
    微信公众号教程(1)微信公众账号注册、设置、登陆
    二级c程序设计题(2)
    二级c程序设计题(1)
    C++经典编程题#6:分配病房
    C++经典编程题#5:寻找下标
    python-----面向对象三大特性
  • 原文地址:https://www.cnblogs.com/heliusKing/p/11581463.html
Copyright © 2011-2022 走看看