java深度克隆和浅度克隆

java进行对象复制当然客以new 一个新的对象然后把原来对象的属性值挨个复制到新的对象中去,可万一属性三四十个呢,不是很麻烦,于是便有了Java的Clone方法

Java对象要想具有Clone方法,首先要实现Cloneable接口,重写Clone()方法,如

public class A  implements Cloneable{

	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	

}

Test方法

public void Test1() throws CloneNotSupportedException{
		A a=new A();
		a.setAge(22);
		a.setName("张三");
		A a1=(A) a.clone();
		System.out.println(a1==a);
		System.out.println(a1.getName()+":"+a1.getAge());		
	}

结果:

false
张三:22

 

可见Clone生成两个不同的对象,而不仅仅是复制了地址的引用

但是有个问题是,Clone() 只支持全局变量类型为8种基本类型和String类型的复制,对比如Date,ArrayList等其他引用类型只是复制了地址引用,这样Clone出来的对象就失去了原有的意义了,即成为浅度复制

如:

package cn.zw.learn.prototype;

public class A  implements Cloneable{

	private String name;
	private int age;
	private B b;	
	public B getB() {
		return b;
	}
	public void setB(B b) {
		this.b = b;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	

}

测试

 

	public void Test1() throws CloneNotSupportedException{
		A a=new A();
		a.setAge(22);
		a.setName("张三");
		B b=new B();
		b.setName("裤子");
		a.setB(b);
		A a1=(A) a.clone();
		System.out.println(a1==a);
		System.out.println(a.getB()==a1.getB());		
		System.out.println(a1.getName()+":"+a1.getAge());		
	}

}

结果

false
true
张三:22

这样两个对象就不完全独立,失去了克隆的意义

为了解决这一问题,我们在实现的clone()方法中,用序列化反序列化的方式得到一个新的Object并把它作为返回值返回,做深度复制

改造如下

B类加上实现序列化接口

A类改造如下

package cn.zw.learn.prototype;

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



public class A  implements Cloneable,Serializable{

	private String name;
	private int age;
	private B b;	
	public B getB() {
		return b;
	}
	public void setB(B b) {
		this.b = b;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		ByteArrayOutputStream bos=null;
		ObjectOutputStream oos=null;
		ObjectInputStream ois=null;
		try {
			bos=new ByteArrayOutputStream();
			oos=new ObjectOutputStream(bos);
			oos.writeObject(this);			
	        ois=new ObjectInputStream( new ByteArrayInputStream(bos.toByteArray()));
	        A a1= (A) ois.readObject();
			return a1;
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//下面的部分为关闭流主要是上面的部分
			if (oos!=null) {
				try {
					oos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
			if (ois!=null) {
				try {
					ois.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
			if (oos!=null) {
				try {
					oos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
		}
		
	
		return null;
	}
	

}

测试类大致不变

	public void Test1() throws CloneNotSupportedException{
		A a=new A();
		a.setAge(22);
		a.setName("张三");
		B b=new B();
		b.setName("裤子");
		a.setB(b);
		A a1=(A) a.clone();
		System.out.println(a1==a);
		System.out.println(a.getB()==a1.getB());		
		System.out.println(a1.getName()+":"+a1.getAge()+"," +a1.getB().getName());		
	}

}

 

结果如下

false
false
张三:22,裤子

完全没有关系的两个对象,且属性全部复制,深度Clone

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章