对象的克隆,前提,对象对应的类,应当事先Clonable接口(便直接扣)
浅克隆:就是调用对象的clone方法
深克隆:就是对象的放序列化
对象浅克隆需要注意的细节
1、如果一个对象要调用clone方法方法克隆,该对象所属的类必须要实现Cloneable接口
2、Cloneable接口只是一个标志接口,没有任何的方法
3、对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有
把另外一个对象也克隆一份.不然就要使用对象的深克隆
4、对象的浅克隆也不会调用构造方法,之前对象的反序列化也不会调用构造方法。
1 package review.test; 2 3 import java.io.Serializable; 4 5 class Address{ 6 String city; 7 public Address(String city) { 8 this.city = city; 9 } 10 } 11 12 class Student implements Serializable, Cloneable 13 { 14 int id; 15 String name; 16 Address address; 17 18 public Student(int id, String name) { 19 this.id = id; 20 this.name = name; 21 } 22 23 public Student(int id, String name, Address address) { 24 this.id = id; 25 this.name = name; 26 this.address = address; 27 } 28 @Override 29 public Object clone() throws CloneNotSupportedException { 30 // TODO Auto-generated method stub 31 return super.clone(); 32 } 33 } 34 35 public class Demo2 { 36 public static void main(String[] args) { 37 try { 38 Address address = new Address("阜阳"); 39 Student stu1 = new Student(68, "yuchen", address); 40 Student stu2 = (Student) stu1.clone(); 41 42 System.out.println(stu1.address); 43 System.out.println(stu2.address); 44 45 46 47 } catch (CloneNotSupportedException e) { 48 throw new RuntimeException(e); 49 } 50 } 51 }
这里注意:
clone方法是object里面的一个protected方法,protected之内在本类以及子类中看的见,别的类中是无法直接使用的。这是我们采取的策略使在Person类中重写clone方法,子类的访问权限可以比父类的大,我们把子类clone方法的访问权限改为public,这样在Demo2方法中就能直接调用stu.clone()方法,否则将会报错"this method is not visible".
接着看下面是对象的深克隆:
对象的深克隆:对象的深克隆就是利用了对象的输入输出流,先把对象写到文件上,然后再读出来,这个过程叫做对象的深克隆
其实就是对象的序列化,这一块别忘了前面介绍到的,对象的序列化的时候要实现标志类Serializable
ObjectInputStream 对象的输入流 都不具备读写能力
ObjectOutputStream 对象的输出流
Demo2 对象的深克隆
1 public class Demo2 { 2 public static void main(String[] args) throws IOException, ClassNotFoundException { 3 Address address = new Address("阜阳"); 4 Person p1 = new Person(110, "狗娃", address); 5 6 writeObj(p1); 7 8 Person p2 = readObj(); 9 10 p2.address.city = "长沙"; 11 System.out.println("p1 = "+p1); 12 System.out.println("p2 = "+p2); 13 } 14 15 //再从文件中读取对象的信息 16 public static Person readObj() throws IOException, ClassNotFoundException 17 { 18 ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("F:\obj.txt")); 19 20 return (Person) inputStream.readObject(); 21 } 22 23 24 //先要把对象写到文件上 25 public static void writeObj(Person p) throws IOException 26 { 27 ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("f:\obj.txt")); 28 29 objectOutputStream.writeObject(p); 30 31 //关闭资源 32 objectOutputStream.close(); 33 } 34 }