JavaSE--对象克隆

当拷贝一个变量时,原始变量与拷贝变量引用同一个对象,这就是说,改变一个变量所引用的对象将会对另一个变量产生影响。

 如果创建一个对象的新的 copy,他的最初状态与 original 一样,但以后将可以各自改变各自的状态,那就需要使用 clone 方法。

但是 clone 默认的是浅拷贝。

clone 方法是 Object 类的一个 protected 方法,也就是说,在用户编写的代码中不能直接调用它。

clone 方法只对各个域进行对应的拷贝。如果对象中的所有数据域都属于数值或基本类型,这样拷贝域没有任何问题。但是,如果在对象中包含了子对象的引用,拷贝的结果会使得两个域引用同一个子对象,因此原始对象与克隆对象共享这部分信息。

如果原始对象与浅克隆对象共享的子对象是不可变的,将不会产生任何问题。然而,更常见的是子对象可变,因此必须重新定义 clone 方法,以便实现克隆子对象的深拷贝。

如果需要做拷贝,必须实现 Cloneable 接口,Cloneable 是一个标记接口,表明类设计者知道要进行克隆处理。如果一个对象需要克隆,而没有实现 Cloneable 接口,就会产生一个已检验异常。

实现深拷贝,必须克隆所有可变的实例域。

所有的数组类型均包含了一个 clone 方法,这个方法被设为 public,而不是 protected。

 1 package org.wzh.clone;
 2 
 3 import java.util.Arrays;
 4 import java.util.Date;
 5 
 6 public class CloneDemo1 {
 7 
 8     public static void main(String[] args) throws CloneNotSupportedException {
 9         Student student = new Student("Timo", 11002910, new Date());
10         System.out.println(student + " " + student.getDate().hashCode());
11         Student student2 = student.clone();
12         student2.setDate(new Date());
13         System.out.println(student2 + " " + student2.getDate().hashCode());
14         System.out.println(student + " " + student.getDate().hashCode());
15         
16         int[] array = {1, 2, 3, 4};
17         int[] array2 = array.clone();
18         System.out.println(Arrays.toString(array));
19         System.out.println(Arrays.toString(array2));
20     }
21 
22 }
23 
24 class Student implements Cloneable {
25 
26     private String name;
27     private int no;
28     private Date date;
29 
30     public Student(String name, int no, Date date) {
31         super();
32         this.name = name;
33         this.no = no;
34         this.date = date;
35     }
36     
37     
38 
39     @Override
40     protected Student clone() throws CloneNotSupportedException {
41         // TODO Auto-generated method stub
42         Student student = (Student) super.clone();
43         //错开时间
44         try {
45             Thread.sleep(1000);
46         } catch (InterruptedException e) {
47             // TODO Auto-generated catch block
48             e.printStackTrace();
49         }
50         student.date = (Date) date.clone();
51         return student;
52     }
53 
54 
55 
56     public String getName() {
57         return name;
58     }
59 
60     public void setName(String name) {
61         this.name = name;
62     }
63 
64     public int getNo() {
65         return no;
66     }
67 
68     public void setNo(int no) {
69         this.no = no;
70     }
71 
72     public Date getDate() {
73         return date;
74     }
75 
76     public void setDate(Date date) {
77         this.date = date;
78     }
79 
80 }
原文地址:https://www.cnblogs.com/microcat/p/6949633.html