您的位置:首页 > 编程语言 > Java开发

java中深拷贝和浅拷贝

2015-10-28 10:41 776 查看
先看代码,从结果中分析和总结深拷贝和浅拷贝的区别和实质。

publicclass Father {
public String name;
public int age;
public Father(String name,int age){
this.name=name;
this.age=age;
}
}
public class Person implements Cloneable{
public String name;
private int age;
public Father father;
public Person(String name,int age,Father father){
this.name=name;
this.age=age;
this.father=father;
}
@Override
protected Object clone(){
Person p=null;
try {
p=(Person)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
@Override
public String toString() {
return"Person [name=" +name
+ ", age=" +age +
", fatherName=" +father.name+",fatherAge="+father.age
+
"]";
}
}
客户端程序如下:
publicstaticvoid main(String[] args) {
Person person1 = new Person("son",14,new
Father("father", 52));
Person person2=person1;
System.out.println(person1==person2);//指向同一个对象
Person person3=(Person) person1.clone();
System.out.println(person1==person3);
person3.father.name="wangwu";
System.out.println(person1.father.name);
}
打印结果是:
true
false
Wangwu
我们可以看出person1和person2是指向同一个对象而person1和person3指向不同的对象,通过修改person3的futher的name值person1的也改变了,也就是说person1和person3中futher成员变量指向同一个地址,这时候我们就说这种拷贝是浅拷贝。
修改一下程序将Futher类也实现Cloneable接口
publicclass Father implements Cloneable{
public String name;
public int age;
public Father(String name,int age){
this.name=name;
this.age=age;
}
@Override
public Object clone()throws CloneNotSupportedException
{
return super.clone();
}
}
Person类的代码也作稍微的修改
public class Person implements Cloneable{
public String name;
private int age;
public Father father;
public Person(String name,int age,Father futher){
this.name=name;
this.age=age;
this.father=father;
}
@Override
protected Object clone(){
Person p=null;
try {
p=(Person)super.clone();
p.futher=(Father)father.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
@Override
public String toString() {
return"Person [name=" +name
+ ", age=" +age +
", fatherName=" +father.name+",fatherAge="+father.age
+
"]";
}
}
这样打印的结果是:
true
false
Father
这种拷贝是深拷贝。
浅拷贝是指拷贝对象时仅仅拷贝对象本身(对象中的基本数据类型),而不拷贝对象中包含的引用数据类型,拷贝过后引用数据类型指向被拷贝对象中引用数据类型变量的地址。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
深拷贝代码可以这样写:
public Object clone()throws CloneNotSupportedException {
Person
p=new Person();

p.age=this.age;

p.name=this.name;

p.father=new Futher(father.name,father.age);
returnp;
}
对于拷贝可能我们比较常用的方式是将对象序列化,序列化拷贝对象的缺点是效率比较低。
修改代码如下:
public class Father implements Serializable{
private static final longserialVersionUID
= 1L;
public String name;
public int age;
public Father(String name,int age){
this.name=name;
this.age=age;
}
}

public class Person implements Serializable{
private static final long serialVersionUID
= 1L;
public String name;
private int age;
public Father father;
public Person(String name,int age,Father father){
this.name=name;
this.age=age;
this.father=father;
}

public Object deepCopy()
throws IOException,ClassNotFoundException{

//写对象到流中
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(os);
oos.writeObject(this);

//流中读取对象
ObjectInputStream ois=new ObjectInputStream(newByteArrayInputStream(os.toByteArray()));
Object readObject = ois.readObject();

return readObject;
}
@Override
public String toString() {
return"Person [name=" +name
+ ", age=" +age +
", fatherName=" +father.name+",fatherAge="+father.age
+
"]";
}
}

客户端调用deepCopy()方法也可以实现深拷贝。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: