java的深浅拷贝_Java深浅拷贝

浅拷贝:

浅拷贝(同一个引用):仅仅复制所考虑的对象,而不复制它所引用的对象。

Object类 是所有类的直接或间接父类,Object中存在clone方法,如下

protected native Object clone() throws CloneNotSupportedException;

如果想要使一个类的对象能够调用clone方法 ,则需要实现Cloneable接口, 并重写 clone方法:

packagecopy;class Teacher implementsCloneable

{privateString name;private intage;publicString getName()

{returnname;

}public voidsetName(String name)

{this.name =name;

}public intgetAge()

{returnage;

}public void setAge(intage)

{this.age =age;

}

}class Student2 implementsCloneable {privateString name;private intage;privateTeacher teacher;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}publicTeacher getTeacher() {returnteacher;

}public voidsetTeacher(Teacher teacher) {this.teacher =teacher;

}

@Overridepublic Object clone() throwsCloneNotSupportedException {return super.clone();

}

}public classCopyTest {public static void main(String[] args) throwsCloneNotSupportedException {

Teacher teacher= newTeacher();

teacher.setName("Delacey");

teacher.setAge(29);

Student2 student1= newStudent2();

student1.setName("Dream");

student1.setAge(18);

student1.setTeacher(teacher);

Student2 student2=(Student2) student1.clone();

System.out.println("拷贝后");

System.out.println(student2.getName());//Dream

System.out.println(student2.getAge());//18

System.out.println(student2.getTeacher().getName());//Delacey

System.out.println(student2.getTeacher().getAge());//29

System.out.println("修改老师的信息后------");//修改老师的信息

teacher.setName("Jam");

System.out.println(student1.getTeacher().getName());//Jam

System.out.println(student2.getTeacher().getName());//Jam

System.out.println("修改拷贝后的学生信息后与被拷贝学生信息对比------");

student2.setName("MerGy");

System.out.println(student1.getName());//Dream

System.out.println(student2.getName());//MerGy

}

}

深拷贝:

深拷贝会拷贝独立对象所有的属性,并拷贝属性指向的内存。深拷贝会把要复制的对象和引用的对象都拷贝,所以,深拷贝相比于浅拷贝速度较慢并且花销较大。

package copy;

class Teacher2 implements Cloneable {

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Override

public Object clone() throws CloneNotSupportedException {

return super.clone();

}

}

class Student3 implements Cloneable {

private String name;

private int age;

private Teacher2 teacher;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public Teacher2 getTeacher() {

return teacher;

}

public void setTeacher(Teacher2 teacher) {

this.teacher = teacher;

}

@Override

public Object clone() throws CloneNotSupportedException {

// 浅复制时:

// return super.clone();

// 改为深复制:

Student3 student = (Student3) super.clone();

// 本来是浅复制,现在将Teacher对象复制一份并重新set进来

student.setTeacher((Teacher2) student.getTeacher().clone());

return student;

}

}

public class CopyTest {

public static void main(String[] args) throws CloneNotSupportedException {

Teacher2 teacher = new Teacher2();

teacher.setName("Delacey");

teacher.setAge(29);

Student3 student1 = new Student3();

student1.setName("Dream");

student1.setAge(18);

student1.setTeacher(teacher);

Student3 student2 = (Student3) student1.clone();

System.out.println("拷贝后");

System.out.println(student2.getName());

System.out.println(student2.getAge());

System.out.println(student2.getTeacher().getName());

System.out.println(student2.getTeacher().getAge());

System.out.println("修改老师的信息后-------------");

// 修改老师的信息

teacher.setName("Jam");

System.out.println(student1.getTeacher().getName());//Jam

System.out.println(student2.getTeacher().getName());//Delacey

}

}

利用序列化实现深拷贝

packageblog;importjava.io.ByteArrayInputStream;importjava.io.ByteArrayOutputStream;importjava.io.ObjectInputStream;importjava.io.ObjectOutputStream;importjava.io.Serializable;

public classDeepCopyServiable {public static void main(String[] args) throwsException {

Teacher3 t= newTeacher3();

t.setName("Taylor");

t.setAge(28);

Student3 s1= newStudent3();

s1.setAge(20);

s1.setName("blank space");

s1.setTeacher(t);

Student3 s2=(Student3) s1.deepClone();

System.out.println("拷贝后:");

System.out.println(s2.getName());

System.out.println(s2.getAge());

System.out.println(s2.getTeacher().getName());

System.out.println(s2.getTeacher().getAge());

System.out.println("---------------------------");

t.setName("swift");

System.out.println("修改后:");

System.out.println(s1.getTeacher().getName());

System.out.println(s2.getTeacher().getName());

}

}class Teacher3 implementsSerializable

{privateString name;private intage;publicString getName()

{returnname;

}public voidsetName(String name)

{this.name =name;

}public intgetAge()

{returnage;

}public void setAge(intage)

{this.age =age;

}

}class Student3 implementsSerializable

{privateString name;private intage;privateTeacher3 teacher;publicString getName()

{returnname;

}public voidsetName(String name)

{this.name =name;

}public intgetAge()

{returnage;

}public void setAge(intage)

{this.age =age;

}publicTeacher3 getTeacher()

{returnteacher;

}public voidsetTeacher(Teacher3 teacher)

{this.teacher =teacher;

}public Object deepClone() throwsException

{//序列化

ByteArrayOutputStream bos = newByteArrayOutputStream();

ObjectOutputStream oos= newObjectOutputStream(bos);

oos.writeObject(this);//反序列化

ByteArrayInputStream bis = newByteArrayInputStream(bos.toByteArray());

ObjectInputStream ois= newObjectInputStream(bis);returnois.readObject();

}

}

重写clone方法 与 通过序列化 两种拷贝方式比较:

clone方法:

优点:速度快,效率高

缺点:在对象引用比较深时,使用此方式比较繁琐

通过序列化:

优点:非常简便的就可以完成深度copy

缺点:由于序列化的过程需要跟磁盘打交道,因此效率会低于clone方式

在java语言中,使用new创建对象与使用clone方法复制一个对象有什么不同?

用new创建对象本意是分配内存。程序到new操作符时,首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这就叫对象的初始化。对象初始化完毕后,可以把引用发布到外部,在外部就可以使用这个引用操纵这个对象。

clone在第一步和new相似,都是分配内存的,调用clone方法时,分配的内存和源对象相同,然后在使用原对象中对应的各个域,填充新对象的域,填充完成之后,clone方法返回,一个新的相同对象就能被创建,同样这个新对象的引用发布到外部。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值