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

         从Java 强引用。软引用,弱引用http://blog.csdn.net/jltxgcy/article/details/35558465一文中,我们看到把一个对象赋值给另一个对象,本质上是添加了引用计数。可是它们都指向相同的堆内存。它们是一个对象。假设我们想要一个独立的对象。改怎么办呢?答案是clone。

     

    1、浅拷贝

         浅拷贝是指拷贝对象时只拷贝对象本身(包括对象中的基本变量),而不拷贝对象包括的引用指向的对象。


          ShallowCopy.java

    class Professor0 implements Cloneable {
        String name;
        int age;
     
        Professor0(String name, int age) {
            this.name = name;
            this.age = age;
        }
     
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
     
    class Student0 implements Cloneable {
        String name;// 常量对象。
        int age;
        Professor0 p;// 学生1和学生2的引用值都是一样的。

    Student0(String name, int age, Professor0 p) { this.name = name; this.age = age; this.p = p; } public Object clone() { Student0 o = null; try { o = (Student0) super.clone(); } catch (CloneNotSupportedException e) { System.out.println(e.toString()); } return o; } } public class ShallowCopy { public static void main(String[] args) { Professor0 p = new Professor0("wangwu", 50); Student0 s1 = new Student0("zhangsan", 18, p); Student0 s2 = (Student0) s1.clone(); s2.p.name = "lisi"; s2.p.age = 30; s2.name = "z"; s2.age = 45; System.out.println("学生s1的姓名:" + s1.name + " 学生s1教授的姓名:" + s1.p.name + "," + " 学生s1教授的年纪" + s1.p.age);// 学生1的教授 } }


          结果:


         s2.p改变了s1.p的内容。而s2.name和s2.age没有改变s1.name和s1.age的内容。


    2、深拷贝

         深拷贝不仅拷贝对象本身。并且拷贝对象包括的引用指向的全部对象。

    class Professor implements Cloneable {
        String name;
        int age;
     
        Professor(String name, int age) {
            this.name = name;
            this.age = age;
        }
     
        public Object clone() {
            Object o = null;
            try {
                o = super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println(e.toString());
            }
            return o;
        }
    }
     
    class Student implements Cloneable {
        String name;
        int age;
        Professor p;
     
        Student(String name, int age, Professor p) {
            this.name = name;
            this.age = age;
            this.p = p;
        }
     
        public Object clone() {
            Student o = null;
            try {
                o = (Student) super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println(e.toString());
            }
            o.p = (Professor) p.clone();
            return o;
        }
    }
     
    public class DeepCopy {
        public static void main(String args[]) {
            long t1 = System.currentTimeMillis();
            Professor p = new Professor("wangwu", 50);
            Student s1 = new Student("zhangsan", 18, p);
            Student s2 = (Student) s1.clone();
            s2.p.name = "lisi";
            s2.p.age = 30;
            System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age);// 学生1的教授不改变。
            long t2 = System.currentTimeMillis();
            System.out.println(t2-t1);//耗时
        }
    }

         结果:


         s2.p不能改变s1.p的内容。

    由于是不同对象。


    3、当然我们另一种深拷贝方法。就是将对象串行化:

         可是串行化却非常耗时,在一些框架中,我们便能够感受到,它们往往将对象进行串行化后进行传递。耗时较多。

         DeepCopy2.java

    import java.io.*;
    //Serialization is time-consuming
    class Professor2 implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        String name;
        int age;
     
        Professor2(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
     
    class Student2 implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        String name;// 常量对象。

    int age; Professor2 p;// 学生1和学生2的引用值都是一样的。 Student2(String name, int age, Professor2 p) { this.name = name; this.age = age; this.p = p; } public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException { // 将对象写到流里 ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); // 从流里读出来 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return (oi.readObject()); } } public class DeepCopy2 { /** * @param args */ public static void main(String[] args) throws OptionalDataException, IOException, ClassNotFoundException { long t1 = System.currentTimeMillis(); Professor2 p = new Professor2("wangwu", 50); Student2 s1 = new Student2("zhangsan", 18, p); Student2 s2 = (Student2) s1.deepClone(); s2.p.name = "lisi"; s2.p.age = 30; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // 学生1的教授不改变。

    long t2 = System.currentTimeMillis(); System.out.println(t2-t1);//耗时 } }


          结果:


         s2.p不能改变s1.p的内容。

    由于是不同对象。


         从图中也能看出将对象进行串行化后进行传递,耗时较多。

  • 相关阅读:
    OpenCV——PS 图层混合算法(一)
    PS 滤镜算法原理——照亮边缘
    PS 色调——老照片效果
    PS 滤镜算法原理——浮雕效果
    PS 滤镜算法原理——碎片效果
    PS 滤镜算法原理——染色玻璃
    PS 滤镜算法原理——高反差保留 (High Pass)
    PS图像特效算法——镜像渐隐
    手把手教你写专利申请书/怎样申请专利
    经常使用的webservice接口
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10504957.html
Copyright © 2011-2022 走看看