Java中的Cloneable接口

1.Cloneable接口的作用

Cloneable是标记接口(其方法体为空),它用来表示一个类拥有某些希望具有的特征。实现Cloneable接口的类被标记为可克隆的,而且其对象可以使用Object类中定义的clone()方法克隆。如果没有实现Cloneable类对象,调用clone()就回抛出CloneNotSupportedException异常

java.lang包中的 Cloneable 接口的定义如下所示:

package java.lang

public interface Cloneable{
}

2.克隆(复制)的分类

a.浅复制

b.深复制

如果一个数据类型是基本类型,复制的就是它的值。如果一个数据域是对象,复制的就是该域的引用。

下面通过一个类来演示Cloneable接口的用法,以及深、浅复制区别

public class House implements Cloneable,Comparable<House>{
    private int id;
    private double area;
    java.util.Date whenBuilt;

    public House(int id, double area){
        this.id = id;
        this.area = area;
        whenBuilt = new java.util.Date();
    }

    public int getId() {
        return id;
    }

    public double getArea(){
        return area;
    }

    public java.util.Date getWhenBuilt(){
        return whenBuilt;
    }

    @Override
    /*浅复制*/
    public Object clone(){
        try{
            return super.clone();
        }
        catch (CloneNotSupportedException ex){
            return null;
        }
    }
    /*深复制*/
//    public Object clone(){
//        try{
//            //Perform a shallow copy
//            House houseClone = (House)super.clone();
//            //Deep copy on whenBuilt
//            houseClone.whenBuilt = (java.util.Date)(whenBuilt.clone());
//            return houseClone;
//        }
//        catch (CloneNotSupportedException ex){
//            return null;
//        }
//    }

    @Override
    public int compareTo(House o){
        if(area > o.area)
            return 1;
        else if(area<o.area)
            return -1;
        else
            return 0;
    }
}

      测试类代码、

public class HouseTest {
    public static void main(String[] args){
        House house1 = new House(1,888);
        House house2 = (House)house1.clone();
        System.out.println("* * * * * * * * * * * * * * * * * * * * * * *");
        System.out.println("house1 = house2? "+ house1.equals(house2));
        if(house1.whenBuilt == house2.whenBuilt)
            System.out.println("浅复制");
        else
            System.out.println("深复制");

        System.out.println("* * * * * * * * * * * * * * * * * * * * * * *");
    }
}

  house1和house2是两个内容相同的不同对象。Object类中的clone()方法将原始对象的每个数据域复制给目标对象。

        尽管house1 == house2为假,但是house1.whenBulit == house2.whenBuilt为真。这就是浅复制而不是深复制,这意味着如果数据域是对象类型,那么复制的是对象的引用,而不是他的内容。

* * * * * * * * * * * * * * * * * * * * * * *
house1 = house2? false
浅复制
* * * * * * * * * * * * * * * * * * * * * * *

        如果希望House对象执行深复制,将clone()方法中的代码换成被注解的部分。这时候house1.whenBulit == house2.whenBuilt为假。house1和house2包含两个不同的Date对象

* * * * * * * * * * * * * * * * * * * * * * *
house1 = house2? false
深复制
* * * * * * * * * * * * * * * * * * * * * * *

3. clone方法和 Cloneable接口引发的思考

其一,为什么Object类中的clone方法定义为protected,而不是public?

因为不是每个对象都可以被克隆的。Java的设计者故意强制子类在其对象可克隆的情况下重写表方法。

其二,为什么clone方法不是定义在Cloneable接口中呢?

因为Java提供了一个本地方法来执行一个浅复制以克隆一个对象。由于接口中的方法是抽象的,该本地方法不能在接口中实现。因此,Java的设计者决定在Object类中定义和实现本地clone方法。

其三,为什么0bject类不实现Cloneable接口呢?

答案和第一个问题一样。

其四,House类不实现Cloneable,将会发生什么?

house1. clone()将返回null.

  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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()方法进行相应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值