在Java中浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。
所以到现在,就应该了解了,所谓的浅拷贝和深拷贝,只是在拷贝对象的时候,对 类的实例对象 这种引用数据类型的不同操作而已。
总结来说:
- 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。并且它们之间的hashcode不一样,只是其数据类型字段相同。
- 深拷贝:是对对象,数据类型值and 它们之间的hashcode拷贝;进行对象完完全全的clone();原对象与新对象对比完全相同。
浅拷贝:
1.实现Cloneable
2.成员变量是基本数据类型,也包括String类型
public class ShallowCopy implements Cloneable {
private int age;
private String name;
public ShallowCopy(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public Object clone() {
ShallowCopy s = null;
try {
s = (ShallowCopy) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return s;
}
@Override
public String toString() {
return "{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public static void main(String[] args) {
ShallowCopy sample = new ShallowCopy(1, "wislie");
ShallowCopy cloneObj = (ShallowCopy) sample.clone();
System.out.println("浅度拷贝 (cloneObj == sample):" + (cloneObj == sample)); //false
System.out.println("sample:" + sample); //sample:{age=1, name='wislie'}
System.out.println("cloneObj:" + cloneObj); //cloneObj:{age=1, name='wislie'}
}
}
深拷贝:
有两种实现方式,一种是实现Cloneable,成员变量需要有引用类型的对象;另一种实现了Serializable,对成员变量没有限制.
实现Cloneable的方式:
public class DeepCopy implements Cloneable {
private String value;
private ShallowCopy shaderCopy;
public DeepCopy(String value, ShallowCopy shaderCopy) {
this.value = value;
this.shaderCopy = shaderCopy;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public ShallowCopy getShaderCopy() {
return shaderCopy;
}
public void setShaderCopy(ShallowCopy shaderCopy) {
this.shaderCopy = shaderCopy;
}
@Override
protected Object clone() {
DeepCopy d = null;
try {
d = (DeepCopy) super.clone();
if(shaderCopy != null){
d.setShaderCopy((ShallowCopy) shaderCopy.clone());
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return d;
}
@Override
public String toString() {
return "{" +
"value='" + value + '\'' +
", shaderCopy=" + shaderCopy +
'}';
}
public static void main(String[] args) {
DeepCopy sample = new DeepCopy("high", new ShallowCopy(12, "wislie"));
DeepCopy cloneObj = (DeepCopy) sample.clone();
System.out.println("深度拷贝 (cloneObj == sample):" + (cloneObj == sample)); //false
System.out.println("sample:" + sample); //{value='high', shaderCopy={age=12, name='wislie'}}
System.out.println("cloneObj:" + cloneObj);//{value='high', shaderCopy={age=12, name='wislie'}}
}
}
实现Serializable的方式
public class DeepCopy2 implements Serializable {
private static final long serialVersionUID = 369285298572961L; //最好是显式声明ID
private int len;
private Inner inner;
public DeepCopy2(int len, Inner inner) {
this.len = len;
this.inner = inner;
}
static class Inner implements Serializable {
private static final long serialVersionUID = 369285298572941L; //最好是显式声明ID
private String color;
private int alpha;
public Inner(String color, int alpha) {
this.color = color;
this.alpha = alpha;
}
@Override
public String toString() {
return "Inner{" +
"color='" + color + '\'' +
", alpha=" + alpha +
'}';
}
}
@Override
public String toString() {
return "DeepCopy2{" +
"len=" + len +
", inner=" + inner +
'}';
}
private DeepCopy2 deepClone() {
DeepCopy2 data = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
//将流序列化成对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
data = (DeepCopy2) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return data;
}
public static void main(String[] args) {
DeepCopy2 sample = new DeepCopy2(10, new Inner("blue", 255));
DeepCopy2 copySample = sample.deepClone();
System.out.println("sample==copySample:" + (sample == copySample)); //false
System.out.println("sample:" + sample); //DeepCopy2{len=10, inner=Inner{color='blue', alpha=255}}
System.out.println("copySample:" + copySample); //DeepCopy2{len=10, inner=Inner{color='blue', alpha=255}}
}
}
不管是浅拷贝还是深拷贝,对象的地址都变了;
网友评论