Java浅拷贝和深拷贝

java拷贝分为两种:引用拷贝和对象拷贝

引用拷贝:不需要申请堆内存,只是将拷贝后的的引用指向原来的对象;

对象拷贝:需要申请堆内存,是一个新的对象;(对象拷贝分为深拷贝和浅拷贝),下面予以说明。

1.准备工作。

类:

public class Address implements Serializable{

}
public class User implements Cloneable,Serializable{
	private Address address;
	public void setAddress(Address address) {
		this.address = address;
	}
	public Address getAddress() {
		return address;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	
	//利用串行化来实现深拷贝
	public Object deepClone()throws Exception{
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(this);
		oos.flush();
		ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bis);
		return ois.readObject();
	}
	
}

解释:ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和ByteArrayInputStream的实例向数组中写入或读出byte型数据。在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去。

测试类:

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		User user = new User();
		Address address = new Address();
		user.setAddress(address);
		try {
			//User user1 =(User) user.clone();//测试浅拷贝
			User user1 = (User)user.deepClone();//测试深拷贝
			System.out.println(user==user1);
			System.out.println(user.getAddress()==user1.getAddress());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}


如果仍疑惑可以看下面的升级版

升级:

public class Address implements Serializable{
	
	int a ;

	public int getA() {
		return a;
	}

	public void setA(int a) {
		this.a = a;
	}
	

}

测试类:

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		User user = new User();
		Address address = new Address();
		String name = "avc";
		user.setAddress(address);
		user.setName(name);
		try {
			//User user1 =(User) user.clone();//测试浅拷贝
			User user1 = (User)user.deepClone();//测试深拷贝
			System.out.println(user==user1);
			System.out.println(user.getAddress()==user1.getAddress());
			
			user.getAddress().setA(4);
			System.out.println(user==user1);
			System.out.println(user1.getAddress().getA());//修改user的引用对象之后,查看user1的引用对象是否发生修改,判断address是否仍指向同一对象,来区分是浅拷贝还深拷贝。
			System.out.println(user.getAddress()==user1.getAddress());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

备注:clone方法的浅拷贝特性主要体现在拷贝对象中含有对象和数组的情况,只是拷贝了引用。


参考:

http://blog.csdn.net/u014727260/article/details/55003402

http://blog.csdn.net/chjttony/article/details/7477346



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值