版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011394071/article/details/53154180
java中的深克隆和浅克隆
- 上次说要解析okhttp的源码后部分,说来也惭愧,最近找工作也就没多少时间去整理了。其实底层封装了http协议,再往下就是Socket的封装了,再往下就是TCP/IP协议了。对于数据的传输,归根结底还是跟文件输入输出流那样,通过二进制流的形式进行通信,只是不同的层次做了不同的封装。有空再做分析了。
- 面试过程也会需要准备一些基础知识,有些可能是常见的基础,有些可能是不太常见的,不管怎样,都要复习一下,在看设计模式的时候提到了java中的克隆,而克隆又有深克隆和浅克隆,这到底怎么区分呢
-
结合网上的一些资料,自己写了测试,这里小结一下,并把自己的理解记下,方便后面复习。
-
下面是我个人对概念定义的理解
浅克隆:相当于创建一个新的对象,但这个对象中包含的数据(封装的数据),与原对象封装的数据时公用的,即他们指向同一内存。
深克隆:创建新的对象,原对象封装的数据都重新分配新的内存空间来复制,值是一样的,但内存地址不同。
- 下面通过例子来说明
-
首先是将要被赋值的类
package skxy.com.org; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * @author Administrator 深克隆和浅克隆 */ public class Person implements Cloneable, Serializable { private static final long serialVersionUID = 1L; private String name; private Student student; public String getName() { return name; } public void setName(String name) { this.name = name; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Person(String name, Student student) { super(); this.name = name; this.student = student; } /* 浅复制 */ public Object clone() throws CloneNotSupportedException { Person proto = (Person) super.clone(); return proto; } /* 深复制 */ public Object deepClone() throws IOException, ClassNotFoundException { /* 写入当前对象的二进制流 */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); /* 读出二进制流产生的新对象 */ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } }
-
类中封装的对象所对应的类,这里就写简单一些
package skxy.com.org; import java.io.Serializable; /** * @author Administrator *被克隆的对象封装了这个类的引用 */ public class Student implements Serializable{ }
-
测试类
package skxy.com.org; import java.io.IOException; public class CloneTest { public static void main(String[] args) { // 克隆测试 Person person = new Person("xiaoming",new Student()); try { //浅克隆 Person clone1 = (Person) person.clone(); System.out.println("person.name=" + person.getName() + " student=" + person.getStudent()); System.out.println("clone1.name=" + clone1.getName() + " student=" + clone1.getStudent()); System.out.println("person.getName()==clone1.getName()?"); System.out.println(person.getName()==clone1.getName()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } //深克隆 try { Person deepClone1 = (Person) person.deepClone(); System.out.println("person.getName()==deepClone1.getName()?"); System.out.println(person.getName()==deepClone1.getName()); System.out.println("clone1.name=" + deepClone1.getName() + " student=" + deepClone1.getStudent()); } catch (ClassNotFoundException | IOException e) { e.printStackTrace(); } } }
-
输出结果
person.name=xiaoming student=skxy.com.org.Student@15db9742 clone1.name=xiaoming student=skxy.com.org.Student@15db9742 person.getName()==clone1.getName()? true person.getName()==deepClone1.getName()? false clone1.name=xiaoming student=skxy.com.org.Student@4eec7777
-
可以看到,不管是深克隆还是浅克隆,克隆后封装的数据值是一样的,但浅克隆得到的数据内存地址是一样的,而深克隆是全新的对象。