Cloneable接口、深复制和浅复制

Cloneable接口、深复制和浅复制

Cloneable接口

  • 在看ArrayList源码时遇到这个接口,所以研究了一下

  • public interface Cloneable
    1. 一个类实现Cloneable接口,以指示Object.clone()方法,该方法对于该类的实例进行现场复制是合法的。
    2. 在不实现Cloneable接口的实例上调用对象的克隆方法导致抛出异常CloneNotSupportedException
    3. 按照惯例,实现此接口的类应使用公共方法覆盖Object.clone()。有关覆盖此方法的详细信息,请参阅Object.clone()
  • protected Object clone() throws CloneNotSupportedException
    • 创建并返回此对象的副本。“复制”的精确含义可能取决于对象的类。一般的意图是对于任何对象而言
      • x.clone()!=x为true
      • x.clone().getClass()==x.getClass()为true
        • 这些不是绝对要求
      • x.clone().equal(x)为true
        • 以上也不是绝对要求
      • 个人觉得以上对比只是定义层面的解释,但没有实际意义,因为默认(即不重写equal())情况下,等号运算符equal()方法的行为是一致的

示例

package pojo;

/**
 * @author ssk
 * @date 2020/5/19 18:46
 * @desc
 */
public class Person implements Cloneable{

    private String name;

    private String job;

    public Person(String name, String job) {
        this.name = name;
        this.job = job;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

    @Test
    public void testCloneable() throws CloneNotSupportedException {
        Person person = new Person("卡卡西", "木叶上忍");

        Object clone = person.clone();
        Person person2 = (Person) clone;
        person2.setJob("六代火影");
        System.out.println("x.clone().getClass() == x.getClass():"+(clone.getClass()==person.getClass()));
        System.out.println("x.clone() != x:" + (clone != person));
        System.out.println("x.clone().equals(x):" + (person2.equals(person)));
    }
  • 运行结果:
x.clone().getClass() == x.getClass():true
x.clone() != x:true
x.clone().equals(x):false

深复制和浅复制

以下内容参考自 Cloneable接口和Object的clone()方法

  • 深复制和浅复制描述的是,当对象中还组合有其它对象时
    1. 浅复制时:如果我们要复制对象,只复制它自身以及它所包含的所有对象的引用地址
    2. 深复制时:将其它对象的引用复制值新对象
    3. 对于基本数据类型,无论深复制还是浅复制,都会进行原值拷贝
publice class Person{
    
    private Address address;
    
}
  • 即对于Person来说
    • 如果是深复制:person.getAddress()!=person.clone().getAddress()
    • 如果是浅复制:person.getAddress()==person.clone().getAddress()
posted @ 2020-05-22 15:39  rider_add  阅读(285)  评论(0编辑  收藏  举报