美文网首页
Java | 对象克隆

Java | 对象克隆

作者: tingshuo123 | 来源:发表于2018-08-21 16:17 被阅读3次

    浅拷贝

    默认的克隆操作,也就是Objectclone 方法是浅拷贝,浅拷贝只会拷贝对象属性的值,而不会拷贝对象中属性所引用的对象。

    浅拷贝
    如上图所示,克隆的对象跟原对象共同引用同一个对象,如果其中有一个改变了hireDay的值,另一个对象hireDay的值也会随之改变(因为是同一个引用),这样的结果有时可能并不是我们想要的,这时就需要 深拷贝

    深拷贝

    深拷贝会将对象及其属性引用的对象一同拷贝,这样的话每个对象及其属性引用的对像都是相互独立的就不会发生上面的问题了,想要实现深拷贝需要重写Object类的 clone 方法。

    另外,因为不可变对象不可修改,如 String,所以不存在上面所说的问题,深拷贝时不用考虑不可变对象。

    实现深拷贝

    想要使用clone方法的对象必须满足以下要求:

    1. 实现 Cloneable 接口
    2. 重写 clone 方法,并将访问修饰符改为public(默认是protected)
      如:
    public class Person implements Cloneable{
        // ...
        @Override
        protected Object clone() throws CloneNotSupportedException {
    
            return super.clone();
        }
    }
    

    深拷贝需要将对象属性引用的可变对象逐个拷贝 如

    public class Person implements Cloneable{
    
        private String name;
        private String sex;
        private Date brithday;  // 可变对象
        
        // 重写 Object 的 clone 方法
        @Override
        public Object clone() throws CloneNotSupportedException {
            // 克隆本对象
            Person cloned = (Person) super.clone();
    
            // 克隆本对象属性引用的可变对象
            cloned.brithday = (Date) this.brithday.clone();
    
            return cloned;
        }
    

    为什么要实现 Cloneable 接口

    核心编程上说 Cloneable 接口是 Java 提供的一组标记接口(tagging interface)之一,标记接口是不包含任何方法得,它唯一的作用就是允许在类型中查询使用 instanceof 关键字。

    从上面可以知道,就算没有 Cloneable 接口我们也可以重写clone方法,因为 clone 方法是Object的,但是如果类没有实现 Cloneable 接口,调用了clone 方法,运行时就会报 CloneNotSupportedException 异常,所以想要正常调用clone 方法,就必须实现Cloneable 接口。

    将重写 clone 的方法默认是 protected 如果不声明为 public是不能在别的类调用的(只能在自己跟子类中调用或者同包的类),上面例子中的Date对象能在Person中调用是因为 Date 这个类已经重写并将修饰符改成了 public

    Java还可以通过 序列化实现对象克隆,简单易用,就是效率没有 clone 方法高。

    相关文章

      网友评论

          本文标题:Java | 对象克隆

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