java深入理解浅拷贝和深拷贝深入理解浅拷贝和深拷贝
拷贝对象是java中经常会遇到的问题。java中存在两种类型,基础类型和引用类型。
java的赋值都是传值的,对于基础类型来说,会拷贝具体的内容,但是对于引用对象来说,存储的这个值只是指向实际对象的
地址,拷贝也只会拷贝引用地址。
因为引用对象的存在,所以经常会出现和预期不一样的情况。
本文将会深入的探讨一下在拷贝对象中会出现的浅拷贝和深拷贝的情况。
拷贝接口拷贝接口
java中所有的对象都是继承自java.lang.Object。Object对象中提供了一个clone方法,来供我们对java对象进行拷贝。
protected native Object clone() throws CloneNotSupportedException;
这个clone方法是native的,所以不需要我们来实现,但是注意clone方法还是protected,这意味着clone方法只能在java.lang包
或者其子类可见。
如果我们想要在一个程序中调用某个对象的clone方法则是不可以的。因为clone方法是定义在Object中的,该对象并没有对外
可见的clone方法。
JDK的建议是让我们去实现接口Cloneable,实现了这个接口就表示这个对象可以调用Object的clone方法。
注意,即使你实现了Cloneable接口,还是无法在外部程序中调用该对象的clone方法:
public interface Cloneable {
}
因为Cloneable是空的,明没有强制要你去实现clone方法。
这是JDK在设计上的问题,导致clone方法并不像预期那么好用。
首先clone只是对象的拷贝,它只是简单的拷贝对象,而不会去执行对象的构造函数。
其次clone会导致浅拷贝的问题。
使用使用clone导致的浅拷贝导致的浅拷贝
我们举个clone产生的浅拷贝的例子,我们定义一个对象中的对象,然后尝试拷贝:
@Data
public class Address implements Cloneable{
private String name;
//不是好的方式
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Data
public class CustUser implements Cloneable{
private String firstName;
private String lastName;
private Address address;
private String[] cars;
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
上面的例子中,我们定义了CustUser和Address。
评论10