java Object 类中clone方法使用java clone方法学习理解java 浅克隆和深度克隆区别

                             java Object 类中clone方法使用java clone方法学习理解

 

一、clone方法使用步骤

1、在当前类中实现接口: java.lang.Cloneable

2、重写 clone方法,将访问修饰符由 protected 调整 public

二、浅克隆

1、 浅克隆: 当前对象中 引用类型 和 克隆后的对象中引用类型 数据共享容易引起变量污染。

2、 定义一个类 ShadowClone,里面有基本数据类型和引用数据类型。

/**
* description: shadow 浅克隆
* @version v1.0
* @author w
* @date 2018年7月18日上午10:40:07
*/
public class ShadowClone implements Cloneable{
    private int age ;
    private int[] ages ;
    /**
    * 重写父类的 clone 方法
    * @throws CloneNotSupportedException
    */
    @Override
    protected ShadowClone clone() throws CloneNotSupportedException {
        return (ShadowClone)super.clone();
    }

    @Override
    public String toString() {
        return "ShadowClone [age=" + age + ", ages=" + Arrays.toString(ages) + "]";
    }
    // 省略 getter , setter 方法
}

3、 定义 ShadowTest 针对 ShadowClone 类的测试

/**
* description: 针对 浅 clone 的测试
* @version v1.0
* @author w
* @date 2018年7月18日上午10:41:56
*/
public class ShadowTest {

    public static void main(String[] args) throws Exception{
        ShadowClone s1 =new ShadowClone();
        s1.setAge(111);
        s1.setAges(new int[]{1,2,3});
        System.out.println("克隆前:"+s1);
       
        ShadowClone s2 = s1.clone();
        System.out.println("克隆后:"+s2);
        System.out.println(s1 == s2); // false ---> 地址值不一致,说明克隆后的对象和克隆前的对象不是同一个对象。
        System.out.println(s1.getAge() == s2.getAge()); // true
        System.out.println(s1.getAges() == s2.getAges()); // true ---> 数组引用类型,地址值一致,说明共享了。
    }

}

三、 深克隆

1、深克隆:和浅克隆相对,当前对象中引用类型和克隆后对象中引用类型 数据不共享,从而可以避免变量污染。

2、 定义一个类 DeepClone,重写clone方法,对引用类型数据也进行克隆。

/**
* description: 深度clone, 类中引用类型都需要进行深度clone
* @version v1.0
* @author w
* @date 2018年7月18日上午11:02:46
*/
public class DeepClone implements Cloneable{
    private String name ;
    private int age ;
    private int[] ages;
    /**
    * 重写clone方法,对当前类中引用类型数据也进行克隆
    */
    @Override
    public DeepClone clone() throws CloneNotSupportedException {
        DeepClone deep =(DeepClone)super.clone();
        deep.ages=Arrays.copyOf(ages, ages.length);
        deep.name=new String(name);
        return deep;
    }
    @Override
    public String toString() {
        return "DeepClone [name=" + name + ", age=" + age + ", ages=" + Arrays.toString(ages) + "]";
    }
    // 省略 getter , setter 方法
}

3、定义 DeepTest 针对 DeepClone 类的测试

/**
* description: 针对深度clone 的测试
* @version v1.0
* @author w
* @date 2018年7月18日上午11:06:03
*/
public class DeepTest {

    public static void main(String[] args) throws Exception{
        DeepClone d = new DeepClone();
        d.setAge(111);
        d.setAges(new int []{111,222,333});
        d.setName("淘宝");
        System.out.println(d);

        DeepClone d2 = d.clone();
        System.out.println(d2);
        System.out.println(d == d2); // false
        System.out.println(d.getAges() == d2.getAges()); // false
        System.out.println(d.getName() == d2.getName()); // false
    }
}

 

四、总结

1、clone方法,用于对象的拷贝,使用前提是:

  • 当前类必须实现 java.lang.Cloneable 接口,

  • 重写 clone 方法

2、不使用 new 关键字创建对象, clone 方法算是一种 。

3、clone 默认的是浅拷贝,要想实现深度拷贝,必须手动对需要拷贝对象中的引用类型数据手动逐一拷贝。

 

 

五、参考资料

1、 这里只是简单的介绍了下 clone 方法的使用,要了解更多请参考以下大佬的博文:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值