深拷贝与浅拷贝

代码见:点击打开链接


1.深拷贝与浅拷贝的定义(看成员对象)

   深拷贝(又叫深复制,深克隆):对象所包含的成员对象是值传递。


    浅拷贝(又叫浅复制,浅克隆):对象包含的成员对象是引用传递。


2.关于拷贝的一些问题(改变一个对象,虽然说是改变一个变量A,但是心中要知道那是要改变A所指向的内存的值。所以不管是值传递还是引用传递,其实传的都是值,只不过,传引用时,传的是别名(指针)的值。那为什么基本类型传的不是引用呢?那是因为基本类型根本不需要指针或引用去表示(简化)它,它们完全可以直接存储到计算机中)

2.1关于返回值是深拷贝还是浅拷贝的问题

返回值是基本类型,想都不用想,那肯定是值传递啦!

返回值是非基本类型:是引用传递

java中函数返回值的生命周期(该问题和文章主题有所偏差):返回值是一个常量。根本不存在生命周期这一说法,并且java中只要有引用指向的变量,这个变量就死不了。下面代码只看红色波浪线部分。


红色波浪线处报错:The left-hand side of an assignment must be a variable。说明返回值根本不是一个变量。

java中对每一个变量的操作,都是要先判断它的类型(是基本类型还是非基本类型),然后在进行相应的操作。


2.2关于java中拷贝构成函数问题

    java中根本就不存在拷贝构造函数一说。为什么java中没有拷贝构造函数一说?那我们就要来看看为什么C++中要用拷贝构造函数了。参考点击打开链接,具体例子点击打开链接。链接中已经说明了C++存在拷贝构造函数的原因了。

  • 当一个对象作为函数参数,以值传递的方式传入函数体;
  • 当一个对象作为函数返回值,以值传递的方式从函数返回;
  • 当一个对象用于给另外一个对象进行初始化(常称为赋值初始化, A b;A a=b,这里‘=’时自动调用拷贝构造函数);

拷贝构造函数的调用都是自动调用的。

然而在java中,就是你写了,那也不是拷贝构造函数,因为它不自动调用。当然你能说它是构造函数,但它绝不是C++中的拷贝构造函数。

2.3关于深拷贝时,成员对象里面又有成员对象问题。

3.浅拷贝实现

参考点击打开链接,写得比我好多了。总结起来有如下几点:

  • 深拷贝和浅拷贝都是对象拷贝
  • 可以用实现cloneable借口的方法实现深拷贝和浅拷贝,而是否深拷贝还是浅拷贝取决于你对成员对象的处理(这样我还不如直接写一个参数为本类型构造函数,还不用实现接口或重写接口)
  • 可以利用序列号的方法实现深拷贝。

自我感觉。写拷贝函数,还不如直接写个构造函数就行了,既可以深拷贝,又可以浅拷贝,并且还简单。当然在不知道一个对象的组成时,可以用序列化类实现深拷贝。


4.深拷贝实现

深拷贝有两种实现方式,一种是实现cloneable接口,一种是序列化。下面是例子的uml类图


(1)cloneable方法实现

PiFu.java

/**
 * @author 冯利
 * @version 创建时间:2018年4月30日 下午3:37:48
 * 皮肤类
 */
public class PiFu implements Cloneable{
	//皮肤颜色
	private String color;
	//皮肤售价
	private int price;
	public PiFu(String color,int price)
	{
		this.color=color;
		this.price=price;
	}
	public PiFu()
	{
		color="暗红色";
		price=1280;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	
	
	
}

LuoShou.java

/**
 * 
 * @author 冯利
 * @version 创建时间:2018年4月30日 下午3:38:50
 * 洛手类
 */
public class LuoShou implements Cloneable {
	//洛手的皮肤
	private PiFu pf=new PiFu();
	//洛手的等级
	private int range;
	public PiFu getPf() {
		return pf;
	}
	public void setPf(PiFu pf) {
		this.pf = pf;
	}
	public int getRange() {
		return range;
	}
	public void setRange(int range) {
		this.range = range;
	}
	public Object deepClone() throws CloneNotSupportedException
	{
		LuoShou cloned=(LuoShou) super.clone();
		cloned.setPf((PiFu)pf.clone());
		return cloned;
		
	}
	public Object shallowClone() throws CloneNotSupportedException
	{
		LuoShou cloned=(LuoShou) super.clone();
		return cloned;
	}
	
}

Main.java



public class Main {


	public static void main(String[] args) throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		LuoShou ls = new LuoShou();
		PiFu pf = new PiFu("绿色", 6300);
		ls.setPf(pf);
		System.out.println(ls.getPf().getColor());
		
		
		LuoShou deepCloned = (LuoShou) ls.deepClone();
		LuoShou shallowCloned = (LuoShou) ls.shallowClone();
		pf.setColor("红色");
		System.out.println(deepCloned.getPf().getColor());
		System.out.println(shallowCloned.getPf().getColor());
		
		
	}


}

运行结果:



(2)序列化实现方法

PiFu.java

import java.io.Serializable;

/**
 * @author 冯利
 * @version 创建时间:2018年4月30日 下午3:37:48
 * 皮肤类
 */
public class PiFu implements Serializable{
	//皮肤颜色
	private String color;
	//皮肤售价
	private int price;
	public PiFu(String color,int price)
	{
		this.color=color;
		this.price=price;
	}
	public PiFu()
	{
		color="暗红色";
		price=1280;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	
	
	
}

LuoShou.java

import java.io.Serializable;

/**
 * @author 冯利
 * @version 创建时间:2018年4月30日 下午3:37:48
 * 皮肤类
 */
public class PiFu implements Serializable{
	//皮肤颜色
	private String color;
	//皮肤售价
	private int price;
	public PiFu(String color,int price)
	{
		this.color=color;
		this.price=price;
	}
	public PiFu()
	{
		color="暗红色";
		price=1280;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	
	
	
}

Main.java

import java.io.IOException;

public class Main {

	public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
		// TODO Auto-generated method stub
		LuoShou ls = new LuoShou();
		PiFu pf = new PiFu("绿色", 6300);
		ls.setPf(pf);
		System.out.println(ls.getPf().getColor());
		
		
		LuoShou deepCloned = (LuoShou) ls.deepClone();
		//LuoShou shallowCloned = (LuoShou) ls.shallowClone();
		pf.setColor("红色");
		System.out.println(deepCloned.getPf().getColor());
		//System.out.println(shallowCloned.getPf().getColor());
		
		
	}

}


运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值