java中关于clone的理解

       首先作为我的第一篇博客,我还是很想写好,当做一个好的开头,原因是作为一位大二学信息工程的学生,我的编程实在拉跨,朋友建议将我学到的东西以博客的形式展现出来,慢慢提升自己。所以我就开始了。

接下来为大家带来我最近新学的知识,关于java里的clone的一些自己的理解。因此如果有什么错误的地方,欢迎大家的指正。

目录

一、clone()简介

二、浅拷贝、深拷贝

三、举例


一、clone()简介

   clone顾名思义就是复制的意思,在java中,clone主要被用来创建对象的副本,它的默认行为是浅拷贝,如果想要实现深拷贝就需重写clone(),即在clone()中添加逻辑达到深拷贝的目的。为了更好理解clone(),我先说一下什么是浅拷贝和深拷贝。

二、浅拷贝、深拷贝

浅拷贝:浅拷贝是只复制对象本身,而不复制它的内部引用。换句话理解就是:浅拷贝指的是在拷贝对象时,新对象和原对象的引用指向相同的内存地址,因此它们共享相同的内部对象。这意味着,如果你对其中一个对象进行修改,可能会影响到另一个对象。

深拷贝:深拷贝是完完全全创建一个独立的新个体,除了它们的内容一样,所指的地址完全不一样。

浅拷贝可以理解为是同一个人,两个变量指向同一个对象,就比如:小猫叫咪咪还是喵喵都指的是猫,深拷贝可以理解为是两个一模一样的双胞胎,但是是两个单独的个体。

三、举例

接下来的例子是我的老师给我们布置的作业中,关于链表的一段代码,这段代码就使用了浅拷贝。                     

 @Override
    public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
        SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone();
        // 使用Object.clone()方法创建初始副本
        if (size > 0) { // 需要独立的节点链
            other.head = new Node<>(head.getElement(), null);
            Node<E> walk = head.getNext(); // 遍历原始链表的剩余部分
            Node<E> otherTail = other.head; // 记住最近创建的节点
            while (walk != null) { // 创建存储相同元素的新节点
                Node<E> newest = new Node<>(walk.getElement(), null);
                //在每次迭代中,创建一个新节点 newest,它复制了当前遍历到的节点的元素值,但是它的下一个节点暂时设置为 null
                otherTail.setNext(newest);
                //将新节点 newest 添加到新链表的尾部,通过修改 otherTail 指向的节点的 next 属性来实现。
                otherTail = newest;
                //更新 otherTail 指针,使其指向新链表的最后一个节点,以便下一次迭代时可以将新节点连接到它后面。
                walk = walk.getNext();
                //将 walk 指针移动到原始链表的下一个节点,以便下一次迭代。
            }
        }
        return other;
    }

        其中:1.@Override使用注解,表明要开始重写父类或者接口中的方法,此时编译器就会检查这部分的重写是否成功,若失败就会返回错误。

2.

public SinglyLinkedList<E> clone() throws CloneNotSupportedException 

        当没有实现重写clone()方法,则会抛出CloneNotSuppoortedException异常。 

3.

SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone();

        这里将object类型强制转换为SinglyLinkedList<E>类型,原因是,当使用了clone()方法,则它返回的类型是object类型,我们只能使用他的方法,比如toString()、hashCode()等,如果不转换回我们的原类型,那么我们将不能使用我们原类型中定义的方法。

  @Test
    void testClone() {
        try {
            SinglyLinkedList<Integer> clonedList = list.clone();
            assertEquals(list.size(), clonedList.size());
            assertEquals(list.first(), clonedList.first());
            assertEquals(list.last(), clonedList.last());
        } catch (CloneNotSupportedException e) {
            fail("Cloning should be supported.");
        }

这段代码是对上段代码的测试代码,为了避免在修改代码时影响到源代码,导致测试失败,因此这里完全创建一个一模一样的副本用于测试,是深拷贝。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值