问题
Java在处理基本数据类型时,采用的是值传递的方式执行。除此之外的其他类型都是引用传递的方式执行。因此,在Java中从A对象创建出另一个与A对象相同的B对象,例如ArrayList B=A;
通过赋值实现。这样,往往修改B对象时,A对象也会跟着修改。若要改变这种情况,则需要使用clone()方法。
浅复制与深复制
浅复制:
被复制对象的所有变量都有原来的值,而所有对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象而不复制它所引用的对象。
class Obj implements Cloneable{
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Object clone(){
Obj obj=null;
try {
obj=(Obj)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
public class Test {
public static void main(String[] args){
Obj obj=new Obj();
obj.setNum(3);
Obj obj1= (Obj) obj.clone();
obj1.setNum(5);
System.out.println("obj:"+obj.getNum()+"\nobj1:"+obj1.getNum());
}
}
结果为:
obj:3
obj1:5
浅复制步骤:
- 继承Clonable借口
- 重写clone()方法
- 在clone()方法中调用super.clone()方法
- 把浅复制的引用指向原型引用对象新的克隆体
深复制
被复制对象的所有变量都含有原来对象的值,那些引用其他对象的变量将引用新的被复制的对象。换言之,深复制是将所有变量都复制了一遍。
package hexo;
import java.util.Date;
class Obj implements Cloneable{
private int num;
private Date data;
public int getNum() {
return num;
}
public Date getData() {
return data;
}
public void setData(Date data) {
this.data = data;
}
public void setNum(int num) {
this.num = num;
}
public Object clone(){
Obj obj=null;
try {
obj=(Obj)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
obj.data= (Date) this.getData().clone();
return obj;
}
}
public class Test {
public static void main(String[] args){
Obj obj=new Obj();
obj.setNum(3);
obj.setData(new Date());
Obj obj1= (Obj) obj.clone();
obj1.setNum(5);
obj1.setData(new Date(100,10,1));//此处为了演示,用了不推荐的Date构造方法进行初始化
System.out.println("obj:"+obj.getNum()+"\nobj1:"+obj1.getNum());
System.out.println("obj:"+obj.getData()+"\nobj1:"+obj1.getData());
}
}
结果为:
obj:3
obj1:5
obj:Wed Jan 23 14:35:21 CST 2019
obj1:Wed Nov 01 00:00:00 CST 2000