zoukankan      html  css  js  c++  java
  • 深拷贝和浅拷贝

    一 demo演示

    1 Professor类

     1 class Professor implements Serializable, Cloneable {
     2     private static final long serialVersionUID = 1286716519490813020L;
     3     public String name;
     4     public int age;
     5 
     6     // 构造函数是为了CloneUtils json序列化使用
     7     public Professor() {
     8     }
     9 
    10     public Professor(String name, int age) {
    11         this.name = name;
    12         this.age = age;
    13     }
    14 
    15     public Object clone() throws CloneNotSupportedException {
    16         return super.clone();
    17     }
    18 }

    2. Student类

     1 class Student implements Serializable, Cloneable {
     2     private static final long serialVersionUID = -547004870369127943L;
     3     public String name;
     4     public int age;
     5     public Professor p;
     6 
     7     // 构造函数是为了CloneUtils工具类clazz.instance()方法调用 & json序列化使用
     8     public Student() {
     9     }
    10 
    11     public Student(String name, int age, Professor p) {
    12         this.name = name;
    13         this.age = age;
    14         this.p = p;
    15     }
    16 
    17     public Object shallowClone() throws CloneNotSupportedException {
    18         Student s = (Student) super.clone();
    19         //s.p = (Professor) p.clone();  //这句加上就是深拷贝了
    20         return s;
    21     }
    22 }

    3 CloneUtils类

     1 @SuppressWarnings("unchecked")
     2 public class CloneUtils {
     3 
     4     /**
     5      * 浅拷贝
     6      */
     7     public static <T> T shallowClone(T t) {
     8         try {
     9             if (t == null) {
    10                 return null;
    11             }
    12 
    13             Class<? extends T> clazz = (Class<? extends T>) t.getClass();
    14             T instance = clazz.newInstance();
    15 
    16             Field[] fields = clazz.getDeclaredFields();
    17             if (fields != null) {
    18                 for (Field field : fields) {
    19                     int modifiers = field.getModifiers();
    20                     if (Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) { //final的无法拷贝, static的无需拷贝
    21                         continue;
    22                     }
    23                     field.setAccessible(true);
    24                     field.set(instance, field.get(t));
    25                 }
    26             }
    27             return instance;
    28         } catch (Exception e) {
    29             System.out.printf("error" + e);
    30             // ignore
    31         }
    32         return null;
    33     }
    34 
    35     /**
    36      * 深拷贝
    37      */
    38     public static <T> T deepClone(T t, Class<T> clazz) throws IOException {
    39         try {
    40             if (t == null || clazz == null) {
    41                 return null;
    42             }
    43             return JsonUtils.toBean(JsonUtils.toJson(t), clazz);
    44         } catch (Exception e) {
    45             System.out.printf("error" + e);
    46             // ignore
    47         }
    48         return null;
    49     }
    50 }

    4 Main

     1 class Main {
     2     public static void main(String[] args) throws IOException, ClassNotFoundException, CloneNotSupportedException {
     3         Professor p = new Professor("教授1", 50);
     4         Student s1 = new Student("学生1", 18, p);
     5 //        Student s2 = (Student) s1.shallowClone();
     6 //        Student s2 = CloneUtils.shallowClone(s1);
     7         Student s2 = CloneUtils.deepClone(s1, Student.class);
     8         s2.p.name = "教授2";
     9         s2.p.age = 30;
    10         s2.name = "学生2";
    11         s2.age = 25;
    12         System.out.println(s1.name + " " + s1.age + " " + s1.p.name + " " + s1.p.age);
    13     }
    14 }

     第5行输出结果:   学生1 18 教授2 30

     第6行输出结果:   学生1 18 教授2 30

     第7行输出结果:    学生1 18 教授1 50

    二 分析

    上面的shallow clone只是实体的所有数据&引用进行了简单拷贝,这样会出现修改拷贝类s2中的引用指针p时,会影响原始的实体s1.p,造成不可预知的错误

    可以看到把Student类中的引用p也进行clone就是深拷贝了(Student#line19注释打开)

    或者直接用序列化的方式进行深拷贝,深拷贝的原始实体和拷贝实体毫无关系,不会互相影响

  • 相关阅读:
    DataWindow修改的单元格文字颜色改变
    DataWindow奇偶行颜色显示不同
    Retrieve时不清除DataWindow原有数据
    Camera拍照声设定
    使用Log.isLoggable方法
    Android Audio遇到播放无声时的分析
    耳机jack构造及在应用时可能出现的问题
    【Android】使用persist属性来调用脚本文件
    [Android][Audio] audio_policy.conf文件分析
    Android4.4 耳机检测分析
  • 原文地址:https://www.cnblogs.com/balfish/p/8182989.html
Copyright © 2011-2022 走看看