克隆

JAVA 专栏收录该内容
3 篇文章 0 订阅

Java语言就提供了克隆机制。看到“克隆”二字,我们可能会有一些疑问。

疑问一:克隆针对的是类还是对象?
答:java语言中克隆针对的是对象
疑问二:Java如何实现克隆?
答:必须实现Cloneable接口,且重写接口里的clone()

实际上,克隆调用的是Object类的clone()方法,clone()是一个本地方法,默认的修饰符是protected。

protected native Object clone() throws CloneNotSupportedException;

实现克隆:

@Data
class User implements Cloneable{
    private int id;          //基本数据类型
    private String userName; //引用数据类型
    private Address address; //引用数据类型

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

@Data
class Address {
    private String addressName;
}

我们用clone方法克隆一个user对象,代码如下:

public static void main(String[] args) throws CloneNotSupportedException {
    Address address = new Address();
    address.setAddressName("新日暮里");

    User user = new User();
    user.setId(1);
    user.setUserName("vans");
    user.setAddress(address);

    User userClone= user.clone();
}

我们直接说结论:
1.这个userClone对象和user对象不是同一个对象(内存地址不一样的)。
2.他们的属性值都是一样的,基本数据类型肯定是一样的,引用数据类型的属性也是一样的。
对于userClone对象的Address属性对象,它并不是新创建的,而是直接把引用指向了user对象里的Address属性对象的内存地址。
所以userClone对象的Address属性对象和user对象里的Address属性对象完全就是一个对象
(其实String也是引用类型,但是它是final修饰的,比较特殊,直接深克隆了)



以上就是浅克隆

如果我们想把user对象在克隆的时候,引用类型属性Address会新创建一个对象,而不是像浅克隆一样只是让引用重新指向原先的内存地址。那么我们可以把Address类也实现Cloneable接口,并重写clone方法。这样user对象再去克隆就成了深克隆了

-----------------------------分割线------------------------------------------

new 一个对象的过程和 clone 一个对象的过程区别
new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。

clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象(即调用 clone 方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填充完成之后,clone 方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值