代码见:点击打开链接
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());
}
}
运行结果: