Cloneable 和 clone()的总结和使用

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

二.克隆的分类  
  (1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。 
  (2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。 

举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。 

三.克隆的举例  
  要让一个对象进行克隆,其实就是两个步骤: 
  1. 让该类实现java.lang.Cloneable接口; 
  2. 重写(override)Object类的clone()方法。
Java代码:   
  1. public class Wife implements Cloneable {  
  2.     private int id;  
  3.     private String name;  
  4.   
  5.     public int getId() {  
  6.         return id;  
  7.     }  
  8.   
  9.     public void setId(int id) {  
  10.         this.id = id;  
  11.     }  
  12.  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.   
  17.     public void setName(String name) {  
  18.         this.name = name;  
  19.     }  
  20.   
  21.     public Wife(int id,String name) {  
  22.         this.id = id;  
  23.         this.name = name;  
  24.     }  
  25.   
  26.     @Override  
  27.     public int hashCode() {//myeclipse自动生成的  
  28.         final int prime = 31;  
  29.         int result = 1;  
  30.         result = prime * result + id;  
  31.         result = prime * result + ((name == null) ? 0 : name.hashCode());  
  32.         return result;  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean equals(Object obj) {//myeclipse自动生成的 
  37.         if (this == obj)  
  38.             return true;  
  39.         if (obj == null)  
  40.             return false;  
  41.         if (getClass() != obj.getClass())  
  42.             return false;  
  43.         Wife other = (Wife) obj;  
  44.         if (id != other.id)  
  45.             return false;  
  46.         if (name == null) {  
  47.             if (other.name != null)  
  48.                 return false;  
  49.         } else if (!name.equals(other.name))  
  50.             return false;  
  51.         return true;  
  52.     }  
  53.   
  54.     @Override  
  55.     public Object clone() throws CloneNotSupportedException {  
  56.         return super.clone();  
  57.     }  
  58.   
  59.     /** 
  60.      * @param args 
  61.      * @throws CloneNotSupportedException  
  62.      */  
  63.     public static void main(String[] args) throws CloneNotSupportedException {  
  64.         Wife wife = new Wife(1,"wang");  
  65.         Wife wife2 = null;  
  66.         wife2 = (Wife) wife.clone();  
  67.         System.out.println("class same="+(wife.getClass()==wife2.getClass()));//true  
  68.         System.out.println("object same="+(wife==wife2));//false  
  69.         System.out.println("object equals="+(wife.equals(wife2)));//true  
  70.     }  
  71. }  
四.浅克隆的举例  
Java代码:  
  1. public class Husband implements Cloneable {  
  2.     private int id;  
  3.     private Wife wife;  
  4.       
  5.     public Wife getWife() {  
  6.         return wife;  
  7.     }  
  8.   
  9.     public void setWife(Wife wife) {  
  10.         this.wife = wife;  
  11.     }  
  12.   
  13.     public int getId() {  
  14.         return id;  
  15.     }  
  16.   
  17.     public void setId(int id) {  
  18.         this.id = id;  
  19.     }  
  20.   
  21.     public Husband(int id) {  
  22.         this.id = id;  
  23.     }  
  24.   
  25.     @Override  
  26.     public int hashCode() {//myeclipse自动生成的  
  27.         final int prime = 31;  
  28.         int result = 1;  
  29.         result = prime * result + id;  
  30.         return result;  
  31.     }  
  32.  
  33.     @Override  
  34.     protected Object clone() throws CloneNotSupportedException {  
  35.         return super.clone();  
  36.     }  
  37.   
  38.     @Override  
  39.     public boolean equals(Object obj) {//myeclipse自动生成的  
  40.         if (this == obj)  
  41.             return true;  
  42.         if (obj == null)  
  43.             return false;  
  44.         if (getClass() != obj.getClass())  
  45.             return false;  
  46.         Husband other = (Husband) obj;  
  47.         if (id != other.id)  
  48.             return false;  
  49.         return true;  
  50.     }  
  51.   
  52.     /** 
  53.      * @param args 
  54.      * @throws CloneNotSupportedException  
  55.     */  
  56.     public static void main(String[] args) throws CloneNotSupportedException {  
  57.         Wife wife = new Wife(1,"jin");  
  58.         Husband husband = new Husband(1);  
  59.         Husband husband2 = null;  
  60.         husband.setWife(wife);  
  61.         husband2 = (Husband) husband.clone();  
  62.         System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true  
  63.         System.out.println("husband object same="+(husband==husband2));//false  
  64.         System.out.println("husband object equals="+(husband.equals(husband)));//true  
  65.         System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true  
  66.         System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//true  
  67.         System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true  
  68.     }  
  69. }  

五.深克隆的举例  
  如果要深克隆,需要重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法; 注意如下代码的clone()方法
Java代码:  
  1. public class Husband implements Cloneable {  
  2.     private int id;  
  3.     private Wife wife;  
  4.       
  5.     public Wife getWife() {  
  6.         return wife;  
  7.     }  
  8.   
  9.     public void setWife(Wife wife) {  
  10.         this.wife = wife;  
  11.     }  
  12.   
  13.     public int getId() {  
  14.         return id;  
  15.     }  
  16.   
  17.     public void setId(int id) {  
  18.         this.id = id;  
  19.     }  
  20.   
  21.     public Husband(int id) {  
  22.         this.id = id;  
  23.     }  
  24.   
  25.     @Override  
  26.     public int hashCode() {//myeclipse自动生成的  
  27.         final int prime = 31;  
  28.         int result = 1;  
  29.         result = prime * result + id;  
  30.         return result;  
  31.     }  
  32.   
  33.     @Override  
  34.     protected Object clone() throws CloneNotSupportedException {  
  35.         Husband husband = (Husband) super.clone();  
  36.         husband.wife = (Wife) husband.getWife().clone();  
  37.         return husband;  
  38.     }  
  39.   
  40.     @Override  
  41.     public boolean equals(Object obj) {//myeclipse自动生成的  
  42.         if (this == obj)  
  43.             return true;  
  44.         if (obj == null)  
  45.             return false;  
  46.         if (getClass() != obj.getClass())  
  47.             return false;  
  48.         Husband other = (Husband) obj;  
  49.         if (id != other.id)  
  50.             return false;  
  51.         return true;  
  52.     }  
  53.   
  54.     /** 
  55.      * @param args 
  56.      * @throws CloneNotSupportedException  
  57.      */  
  58.     public static void main(String[] args) throws CloneNotSupportedException {  
  59.         Wife wife = new Wife(1,"jin");  
  60.         Husband husband = new Husband(1);  
  61.         Husband husband2 = null;  
  62.         husband.setWife(wife);  
  63.         husband2 = (Husband) husband.clone();  
  64.         System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true  
  65.         System.out.println("husband object same="+(husband==husband2));//false  
  66.         System.out.println("husband object equals="+(husband.equals(husband)));//true  
  67.         System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true  
  68.         System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//false  
  69.         System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true  
  70.     }  
  71. }  

但是也有不足之处,如果Husband内有N个对象属性,突然改变了类的结构,还要重新修改clone()方法。解决办法:可以使用Serializable运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

参考java创建对象的第四种方法: 
http://www.software8.co/wzjs/java/2881.html
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值