Java基础之Cloneable接口的用法

1. Cloneable接口的作用

       Cloneable是标记型的接口,它们内部都没有方法和属性,实现 Cloneable来表示该对象能被克隆,能使用Object.clone()方法。如果没有实现 Cloneable的类对象调用clone()就会抛出CloneNotSupportedException。

2. 克隆(拷贝)的分类

      浅克隆(浅拷贝)(shallow clone),浅克隆是指拷贝对象时仅仅copy对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。

      深克隆(深拷贝)(deep clone),不仅copy对象本身,而且copy对象包含的引用指向的所有对象。

      举例:对象X中包含对Y的引用,Y中包含对Z的引用。浅拷贝X得到X1,X1中依然包含对Y的引用,Y中依然包含对Z的引用。深拷贝则是对浅拷贝的递归,深拷贝X得到X1,X1中包含对Y1(Y的copy)的引用,Y1中包含对Z1(Z的copy)的引用。

3. 克隆代码举例

       要让对象可以被克隆,应具备以下2个条件

  • 让该类实现java.lang.Cloneable接口;
  • 重写(Override)Object的clone()方法;
public class Dog implements Cloneable {
    private Integer id;
    private String name;
    private BigDecimal weight;
    private Food food;
 
    public Dog(Integer id, String name, BigDecimal weight) {
        this.id = id;
        this.name = name;
        this.weight = weight;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public BigDecimal getWeight() {
        return weight;
    }
 
    public void setWeight(BigDecimal weight) {
        this.weight = weight;
    }
 
    public Food getFood() {
        return food;
    }
 
    public void setFood(Food food) {
        this.food = food;
    }
 
    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", weight=" + weight +
                ", food=" + food +
                '}';
    }
 
    // 浅拷贝(使用时两者选其一)
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
 
    // 深拷贝(使用时两者选其一)
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object object = super.clone();
        Food food = ((Dog) object).getFood();
        ((Dog) object).setFood((Food) food.clone());
        return object;
    }
}

       引用对象:

public class Food implements Cloneable {
    private String name;
 
    public Food(String name) {
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    public String toString() {
        return "Food{" +
                "name='" + name + '\'' +
                '}';
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

       测试代码: 

public class DogTest {
 
    // 测试浅拷贝
    @Test
    public void test() throws CloneNotSupportedException {
        Dog jack = new Dog(18, "jack", BigDecimal.TEN);
        Dog tom = (Dog) jack.clone();
        tom.setId(19);
        tom.setName("tom");
        tom.setWeight(BigDecimal.ONE);
        System.out.println(jack);
        System.out.println(tom);
    }
 
    // 测试深拷贝
    @Test
    public void test2() throws CloneNotSupportedException {
        Dog jack = new Dog(18, "jack", BigDecimal.TEN);
        jack.setFood(new Food("冰淇淋"));
        Dog tom = (Dog) jack.clone();
        tom.setId(19);
        tom.setName("tom");
        tom.setWeight(BigDecimal.ONE);
        tom.getFood().setName("三明治");
        System.out.println(jack);
        System.out.println(tom);
    }
}
发布了35 篇原创文章 · 获赞 37 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34519487/article/details/103930927