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);
    }
}

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,如果一个类想要实现克隆功能,需要实现Cloneable接口并重写clone()方法。Cloneable接口是一个标记接口,没有任何方法需要实现,但它的存在告诉编译器这个类可以被克隆。 下面是一个示例代码,展示了如何在一个类中实现克隆功能: ```java public class MyClass implements Cloneable { private int number; public MyClass(int number) { this.number = number; } public int getNumber() { return number; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } ``` 在这个示例中,MyClass类实现了Cloneable接口,并且重写了clone()方法。在clone()方法中,我们调用了父类的clone()方法来完成对象的浅拷贝。 要注意的是,clone()方法返回的是Object类型,需要进行类型转换才能得到具体的对象。 使用这个类进行克隆操作的示例代码如下: ```java public class Main { public static void main(String[] args) { MyClass obj1 = new MyClass(10); try { MyClass obj2 = (MyClass) obj1.clone(); System.out.println(obj2.getNumber()); // 输出 10 } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } ``` 在这个示例中,我们创建了一个MyClass对象obj1,并通过调用clone()方法创建了一个新的克隆对象obj2。最后打印出obj2的number属性,结果应该和obj1的number属性相同。 需要注意的是,这里的克隆是浅拷贝,即对象的引用属性不会被复制,而是仍然指向原始对象。如果需要实现深拷贝,即对象的所有属性都被复制一份,可以在clone()方法中进行相应的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值