java对象的克隆
Posted K_artorias
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java对象的克隆相关的知识,希望对你有一定的参考价值。
java对象克隆方式主要有两种:浅克隆和深克隆
首先,不要把对象的克隆和对象的赋值搞混了,看下图
p2 = p1;就是赋值操作,赋值操作只是让被赋值对象指向之前对象的地址,实际上的物理内存是一块,而克隆操作的结果应该是两个对象分别指向内容相同的两块内存。如下就是克隆操作后的状态:
下面说浅克隆和深克隆:
深克隆和浅克隆的区别主要出现在类里有外部类对象时,如下,Person类中有Address类的对象
1 package cn.itcast.copy; 2 3 import java.io.Serializable; 4 5 class Address implements Serializable{ 6 7 String city; 8 9 public Address(String city){ 10 this.city = city; 11 } 12 } 13 14 15 public class Person implements Cloneable,Serializable { 16 17 int id; 18 19 String name; 20 21 Address address; 22 23 public Person(int id, String name) { 24 this.id = id; 25 this.name = name; 26 } 27 28 29 public Person(int id, String name, Address address) { 30 this.id = id; 31 this.name = name; 32 this.address = address; 33 System.out.println("=======构造方法调用了==="); 34 } 35 36 37 @Override 38 public String toString() { 39 return "编号:"+ this.id+" 姓名:"+ this.name+" 地址:"+ address.city; 40 } 41 42 43 @Override 44 public Object clone() throws CloneNotSupportedException { 45 return super.clone(); 46 } 47 }
那么如果对Person类的对象进行克隆就会涉及到浅克隆和深克隆的问题,先用两张图表现浅克隆和深克隆的不同。
第一个图是浅克隆结果,第二个是深克隆结果,也就是说浅克隆只能克隆当前对象,不能克隆当前对象指向的外部类的对象,而深克隆是克隆所有关联的数据和对象。
下面我们说两种克隆的实现:
如果一个类可能涉及到被克隆操作,那么久需要实现Cloneable接口,深克隆还需要实现Serializable 接口(浅克隆不用),如上边的Person就实现了相关接口,浅克隆只需要调用实现的clone方法就可以了:
1 public class Demo1 { 2 3 4 public static void main(String[] args) throws Exception { 5 Address address = new Address("广州"); 6 Person p1 = new Person(110,"狗娃",address); 7 Person p2 = (Person) p1.clone(); //clone() 克隆了一个对象。 8 9 p2.name = "狗剩"; 10 p2.address.city ="长沙"; 11 System.out.println("p1:"+p1); 12 System.out.println("p2:"+ p2); 13 14 } 15 16 }
浅克隆的原理很简单,其简单程度和复制一样好理解,深克隆不同,为了实现深克隆,需要先把需要被克隆的对象保存到制定文件中,然后再把文件中内容赋值给新的对象才能完成克隆,所以就涉及到了流操作:
1 public class Demo2 { 2 3 public static void main(String[] args) throws IOException, ClassNotFoundException { 4 Address address = new Address("广州"); 5 Person p1 = new Person(110,"狗娃",address); 6 writeObj(p1); 7 Person p2 =readObj(); 8 9 p2.address.city = "长沙"; 10 System.out.println("p1:"+ p1); 11 System.out.println("p2:"+ p2); 12 } 13 14 //再从文件中读取对象的信息 15 public static Person readObj() throws ClassNotFoundException, IOException{ 16 FileInputStream fileInputStream = new FileInputStream("F:\\\\obj.txt"); 17 //创建对象的输入流对象 18 ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); 19 return (Person) objectInputStream.readObject(); 20 } 21 22 //先要把对象写到文件上。 23 public static void writeObj(Person p) throws IOException{ 24 //建立一个文件 的输出流对象 25 FileOutputStream fileOutputStream = new FileOutputStream("F:\\\\obj.txt"); 26 //建立对象的输出流 27 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); 28 //把对象写出 29 objectOutputStream.writeObject(p); 30 //关闭资源 31 objectOutputStream.close(); 32 33 } 34 35 }
以上是关于java对象的克隆的主要内容,如果未能解决你的问题,请参考以下文章
GitGit 分支管理 ( 克隆远程分支 | 克隆 master 分支 git clone | 查看远程分支 git branch -a | 克隆远程分支 git checkout -b )(代码片段
GitGit 分支管理 ( 克隆远程分支 | 克隆 master 分支 git clone | 查看远程分支 git branch -a | 克隆远程分支 git checkout -b )(代码片段