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{ 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 测试类代码、
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.



