【Java】3-浅拷贝/ 2-深拷贝

博客介绍了浅拷贝与深拷贝的实现方式。浅拷贝有构造器、Clone()、集合方法三种,底层多调用System.arraycopy(),未对数组内对象处理。深拷贝可让对象内的对象实现Serializable接口,通过字节流拷贝,也可重写Clone()方法,使父层对子层也进行克隆。

三种浅拷贝

  • 构造器:ArrayList newArray = new ArrayList(oldArray);

底层调用Arrays.copyOf()和System.arraycopy()完成拷贝

这里的System.arraycopy()可以等价于数组的Clone(),也是浅拷贝

 

  • Clone():ArrayList newArray = (ArrayList<E>)oldArray.clone();

ArrayList实现了Cloneable接口,调用Object的Clone() --> Object的Clone()是浅拷贝

对于elementData的操作只是让两个ArrayList不共享同一个elementData(因为elementData是数组也就是引用类型)

Arrays.copyOf()底层还是System.arraycopy(),浅拷贝

 

  • 集合方法(等同于一般对象的setter方法,使用=符号):newArray.add(e);

ArrayList<E> newArray = new ArrayList<E>();
    for(E e : oldArray){
        newArray.add(e);
    }

底层也是调用System.arraycopy,所以也是浅拷贝,没有对数组里面的对象做处理

 

  • 集合方法:newArray.addAll(oldArray);

ArrayList<E> newArray= new ArrayList<E>();
newArray.addAll(oldArray);

也用到了System.arraycopy,效果等同于数组对象的Clone(),浅拷贝

 

 

深拷贝

对需要拷贝对象内的对象实现Serializable接口,通过字节流拷贝

class Person implements Serializable{
	String name;
	int age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "姓名:"+this.name+"-年龄:"+this.age;
	}
}
public void deepCopy(ArrayList<Person> oldArray)throws Exception{

    	ByteArrayOutputStream baos = new ByteArrayOutputStream();

    	ObjectOutputStream oos = new ObjectOutputStream(baos);

    	oos.writeObject(oldArray);

    	ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

    	ObjectInputStream ois = new ObjectInputStream(bais);

    	ArrayList<Person> newArray = (ArrayList<Person>)ois.readObject();

}

 

重写Clone()方法

这个比较好理解,因为Clone()方法对于当前调用对象这一层(父层)是深拷贝,只是对调用对象内的子对象(子层)是浅拷贝

也就是说,我们重写父层类的Clone()方法,让其对子层也进行Clone()就可以达到深拷贝的效果

(如果还需要拷贝子对象的孙对象,还需要重写子层的Clone()方法)

*注意:重写和调用Clone()都要实现Clonable接口,不然会报CloneNotSupportException

public class Demo5 implements Cloneable{
	private int age;
	private LittleDemo little;
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Demo5 d = (Demo5)super.clone();
		d.little = (LittleDemo)this.little.clone();
		d.little.toString();
		return d;
	}
	
	public static void main(String[] args) throws CloneNotSupportedException {
		Demo5 d = new Demo5();
		d.age = 5;
		d.little = new LittleDemo();
		Demo5 d2 = (Demo5)d.clone();
		System.out.println("d == d2 :" + (d == d2));
		System.out.println("d.little == d2.little :" + (d.little == d2.little));
	}
}
class LittleDemo implements Cloneable{
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
}

父Demo5,子LittleDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值