美文网首页
浅拷贝和深拷贝

浅拷贝和深拷贝

作者: zxcvbnmzsedr | 来源:发表于2018-06-28 22:22 被阅读0次

    clone方法

    clone是定义一个Object类下基本方法之一:

        protected native Object clone() throws CloneNotSupportedException;
    

    使用的时候需要继承object对象,并且为了可以使其它类调用该方法,覆写克隆方法时必须将其作用域设置为public.

    浅拷贝

    浅拷贝就拷贝了对象本身,属性值不变,也就是说对象里面的引用还是原来对象里面的引用

    class A implements Cloneable {
        int a = 0;
        int[] b = {1, 2};
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            A a = null;
            try {
                a = (A) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return a;
        }
    }
    

    测试一下

    A a = new A();
    A b = (A) a.clone();
    System.out.println(b.a);
    for (int i :b.b) {
        System.out.print(i);
    }
    b.a = 1;
    b.b[0] = 3;
    b.b[1] = 4;
    System.out.println(a.a);
    for (int i :a.b) {
        System.out.print(i);
    }
    
    测试结果是:    
            0  1,2
            0  3,4
    

    因为a是基本类型所以值不变,但是b是引用类型,所以值也被改变了

    深拷贝

    和浅拷贝就一些细微区别,深拷贝是把对象中的属性也进行了一个拷贝

    class A implements Cloneable {
        int a = 0;
        int[] b = {1, 2};
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            A a = null;
            try {
                a = (A) super.clone();
                // 对属性进克隆
                a.b = b.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return a;
        }
    }
    
    测试结果是:    
            0  1,2
            0  1,2
    

    循环引用

    如果类中的对象引用了其他的对象,那么一次次去clone显然不现实

    借助java的序列化,A需要实现序列化接口,而且A中使用的所有对象都要实现序列化接口,否则会抛出NotSerializableException异常

        @Override
        protected Object clone() throws CloneNotSupportedException {
        A a = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
    
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            a = (A) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        return a;
    }
    

    相关文章

      网友评论

          本文标题:浅拷贝和深拷贝

          本文链接:https://www.haomeiwen.com/subject/epanyftx.html