但行好事
莫论前程❤

Java基础学习总结—-Cloneable接口的使用

一.Cloneable 的用途

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

二.克隆的分类

  • 浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。
  • 深克隆(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()方法。
public class Wife implements Cloneable {  
    private int id;  
    private String name;  

    //get/set方法省略

    public Wife(int id,String name) {  
        this.id = id;  
        this.name = name;  
    }  

    @Override  
    public Object clone() throws CloneNotSupportedException {  
        return super.clone();  
    }  

    /** 
     * @param args 
     * @throws CloneNotSupportedException  
     */  
    public static void main(String[] args) throws CloneNotSupportedException {  
        Wife wife = new Wife(1,"wang");  
        Wife wife2 = null;  
        wife2 = (Wife) wife.clone();  
        System.out.println("class same="+(wife.getClass()==wife2.getClass()));//true  
        System.out.println("object same="+(wife==wife2));//false  
        System.out.println("object equals="+(wife.equals(wife2)));//true  
    }  
}  

四.浅克隆的举例

public class Husband implements Cloneable {  
    private int id;  
    private Wife wife;  

    public Wife getWife() {  
        return wife;  
    }  

   //get/set方法 

    @Override  
    protected Object clone() throws CloneNotSupportedException {  
        return super.clone();  
    }  

    /** 
     * @param args 
     * @throws CloneNotSupportedException  
     */  
    public static void main(String[] args) throws CloneNotSupportedException {  
        Wife wife = new Wife(1,"jin");  
        Husband husband = new Husband(1);  
        Husband husband2 = null;  
        husband.setWife(wife);  
        husband2 = (Husband) husband.clone();  
        System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true  
        System.out.println("husband object same="+(husband==husband2));//false  
        System.out.println("husband object equals="+(husband.equals(husband)));//true  
        System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true  
        System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//true  
        System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true  
    }  
} 

五.深克隆的举例

如果要深克隆,需要重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法;注意如下代码的clone()方法

public class Husband implements Cloneable {  
    private int id;  
    private Wife wife;  

   //get/set方法略

    public Husband(int id) {  
        this.id = id;  
    }  

    @Override  
    protected Object clone() throws CloneNotSupportedException {  
        Husband husband = (Husband) super.clone();  
        husband.wife = (Wife) husband.getWife().clone();  
        return husband;  
    }  

    /** 
     * @param args 
     * @throws CloneNotSupportedException  
     */  
    public static void main(String[] args) throws CloneNotSupportedException {  
        Wife wife = new Wife(1,"jin");  
        Husband husband = new Husband(1);  
        Husband husband2 = null;  
        husband.setWife(wife);  
        husband2 = (Husband) husband.clone();  
        System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true  
        System.out.println("husband object same="+(husband==husband2));//false  
        System.out.println("husband object equals="+(husband.equals(husband)));//true  
        System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true  
        System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//false  
        System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true  
    }  
} 

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

赞(0) 打赏
未经允许不得转载:刘鹏博客 » Java基础学习总结—-Cloneable接口的使用
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏