JAVA深复制与浅复制
new语句返还指针引用。基本数据类型按值传递(输入参数复制),其他是按引用传递(对象的一个引用)。对象除了在函数调用时是引用传递,在使用“=”赋值也是采用引用传递。
package cn.itcast.demo;
public class Obj {
private int aInt = 0;
public int getaInt() {
return aInt;
}
public void setaInt(int aInt) {
this.aInt = aInt;
}
public void changeInt(){
this.aInt = 1;
}
}
package cn.itcast.demo;
public class TestRef {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = a;
b.changeInt();
System.out.println("a:" + a.getaInt());
System.out.println("b:" + b.getaInt());
}
}
Object类提供clone()方法,该方法返还object对象复制,该复制函数返还新对象而非引用。
使用步骤:实现clone类要继承Cloneable接口,类中重写Object类的clone()方法,在clone方法调用super.clone()。super.clone会直接或间接调用Object类的clone()方法。把浅复制的引用指向原型对象新的克隆体。
非基本类型的属性需要clone()方法才能完成深复制。
package cn.itcast.demo;
public class Obj implements Cloneable{
private int aInt = 0;
public int getaInt() {
return aInt;
}
public void setaInt(int aInt) {
this.aInt = aInt;
}
public void changeInt(){
this.aInt = 1;
}
public Object clone(){
Object o = null;
try {
o = (Object)super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e);
}
return o;
}
}
package cn.itcast.demo;
public class TestRef {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = a;
b.changeInt();
System.out.println("a:" + a.getaInt());
System.out.println("b:" + b.getaInt());
}
}
上面两个看似相似的方法有着不同的运行结果,主要原因是Java在处理基本数据类型(例如int、char、double等)时,都是采用按值传递(传递的是输入参数的复制)的方式执行,除此之外的其他类型都是按引用传递(传递的是对象的一个应用)的方式执行。’
浅复制与深复制概念
1.浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
2.深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
使用clone方法的步骤:
1)实现clone的类首先需要继承Cloneable接口
2)在类中重写Object类中的.clone方法
3)在clone方法中调用super.clone()
4)把浅复制的引用指向原型对象新的克隆体
浅复制
当类中只有一些基本的数据类型时,采用上述方法就可以;
当类中包含一些对象时,就需要用到深复制;
实现方法是在对对象调用clone()方法完成复制之后,接着对对象中的非基本类型的属性也调用clone方法完成深复制。
package cn.itcast.demo;
import java.util.Date;
public class Obj implements Cloneable{
private Date birth = new Date();
public Date getBirth(){
return birth;
}
public void setBirth(Date birth){
this.birth = birth;
}
public void changeDate(){
this.birth.setMonth(4);
}
public Object clone(){
Obj o = null;
try {
//Object中的clone()识别出你要复制的是哪一个对象
o = (Obj)super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e);
}
//实现深复制
o.birth = (Date)this.getBirth().clone();
return o;
}
}
package cn.itcast.demo;
public class TestRef {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = (Obj) a.clone();
b.changeDate();
System.out.println("a = " + a.getBirth());
System.out.println("b = " + b.getBirth());
}
}