美文网首页
Object类中的clone()方法是深拷贝还是浅拷贝?

Object类中的clone()方法是深拷贝还是浅拷贝?

作者: 纳米君 | 来源:发表于2018-06-06 23:14 被阅读39次

    今天有人给我发来一道题,说的是clone()是深拷贝还是浅拷贝,两眼懵比。既然不懂,那就写代码做个记录吧。

    首先,了解一下深拷贝和浅拷贝的概念。
    当一个对象被拷贝时,拷贝得到的对象内部的引用对象和原对象内部的引用对象地址相等,这是浅拷贝。反之,是深拷贝。

    一个对象能被拷贝,需要两个条件:

    1. 实现Cloneable 接口。
      该接口是个空接口,实现该接口只是使拷贝变得合法,不然会抛异常java.lang.CloneNotSupportedException
    2. 复写clone()方法。

    接下来用代码验证:

    public class Animal implements Cloneable {
    
        public Cat cat;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    public class Cat {
    
    }
    

    测试类:

    public class CloneTest {
    
        public static void main(String[] args) throws CloneNotSupportedException {
            Animal a = new Animal();
            a.cat = new Cat();
            Animal clone = (Animal) a.clone();
            System.out.println("Animal: " + (a == clone));
            System.out.println("cat:" + (a.cat == clone.cat));
        }
    }
    

    打印结果:

    Animal: false
    cat:true
    

    一开始的问题有答案了,clone()方法是浅拷贝,两个对象中的cat指向堆中同一个对象。

    如果想要深拷贝呢?
    这时候就需要改造clone方法了,以及引用的对象中也要实现接口和复写方法。
    上代码:

    public class Animal implements Cloneable {
    
        public Cat cat;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Animal clone = (Animal) super.clone();
            // 引用对象也拷贝一份
            clone.cat = (Cat) cat.clone();
            return clone;
        }
    }
    
    public class Cat implements Cloneable {
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    

    依旧是上面的测试代码,打印结果为:

    Animal: false
    cat:false
    

    以上。

    相关文章

      网友评论

          本文标题:Object类中的clone()方法是深拷贝还是浅拷贝?

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