浅拷贝和深拷贝

2018-06-28  本文已影响0人  zxcvbnmzsedr

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;
}
上一篇下一篇

猜你喜欢

热点阅读