浅拷贝与深拷贝

简介: 浅拷贝与深拷贝

作者简介: zoro-1,目前大一,正在学习Java,数据结构

作者主页: zoro-1的主页

欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

浅拷贝

之前我们学了数组的拷贝,那么对象如何进行拷贝呢

浅拷贝定义

浅拷贝是一种复制对象的方法,在这种方法中,只复制对象的引用或指针,而不是对象本身的内容。

浅拷贝代码演示

class Hia{
    int a=6;
}
class Animal {
    String name="animal";
    int age=0;
    Hia hia=new Hia();
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Text4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Animal dog=new Animal("dog",5);
        Animal dogcopy=(Animal) dog.clone();
    }
}

代码讲解:


初始化Animal类为dog对象,现在想要copy一份dog对象,就要了解clone方法,他是object类里面的方法也就是Animal的父类的方法(因为所有类都是继承object类),这个类是由protected修饰所以我们不能直接调用,他的最大访问权限是不同包下的子类对象,且只能用super访问所以要在定义一个不带static修饰的方法下面访问,我这里采用的是重写父类的clone方法,返回super.clone();,clone的返回值对象是object,所以要强转为(Animal);

上面的代码运行出来结果还是错的

原因是在java里面只有实现Cloneable接口才说明这个类是支持拷贝的(虽然这个接口什么都没有);

浅拷贝的特点

特点是他只是将你类里面的变量的值赋值下来,不会将你成员对象引用的也赋值一份,下面这个图就能很好解释

当然我们也可以用代码直观的看出来

public class Text4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Animal dog=new Animal("dog",5);
        Animal dogcopy=(Animal) dog.clone();
        System.out.println(dog.hia.a);
        System.out.println(dogcopy.hia.a);
        dog.hia.a=9;
        System.out.println(dog.hia.a);
        System.out.println(dogcopy.hia.a);
    }
}

通过运行结果可以看出来我们发现该变原对象的hia.a,复制的对象的hia.a也发生了改变,这说明复制后的hia和前面指向的是同一个引用

想要将复制里面的引用也复制一份就要用到深拷贝

深拷贝

深拷贝定义

深拷贝是指在拷贝一个对象时,创建一个新的对象并将原对象的所有属性值都复制到新对象中,而不是简单地复制对象的引用地址。因此,在深拷贝后,两个对象之间是完全独立的,互不影响。深拷贝通常用于需要完全复制原对象的情况,例如在多线程环境下操作对象时,为了避免不同线程间共享对象导致的数据冲突,就需要使用深拷贝。深拷贝是指在拷贝一个对象时,创建一个新的对象并将原对象的所有属性值都复制到新对象中,而不是简单地复制对象的引用地址。

深拷贝代码演示

class Hia implements Cloneable{
    int a=6;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Animal implements Cloneable{
    String name="animal";
    int age=0;
    Hia hia=new Hia();
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    protected  Object clone() throws CloneNotSupportedException {
        Animal animal=(Animal) super.clone();
        animal.hia=(Hia) animal.hia.clone();
        return animal;
    }
}
public class Text4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Animal dog=new Animal("dog",5);
        Animal dogcopy= (Animal) dog.clone();
        System.out.println(dog.hia.a);
        System.out.println(dogcopy.hia.a);
        dog.hia.a=9;
        System.out.println(dog.hia.a);
        System.out.println(dogcopy.hia.a);
    }
}

代码解释


我的理解是深拷贝是两层浅拷贝,现将对象进行一次拷贝然后再将dog对象里面的引用对象拷贝一份赋值给新的对象的里面的引用对象,譬如上面的代码,重写的clone()方法里面先super.clone(),复制一份当前类的对象,然后类里面的引用类型Hia调用clone(),复制一份再赋值给animal.hia,那现在animal就是就是彻底的拷贝了,然后返回animal;然后改变dog类里面的hia.a打印输出,只有dog类里面的改变了

深拷贝特点

深拷贝是一种复制数据的方式,它会创建一个完全独立的副本,而不是原始数据的引用。深拷贝的特点如下:

1.完全独立:深拷贝会创建一个全新的对象,而不是原对象的引用。

2.完整复制:深拷贝会复制所有的属性和方法,包括对象的嵌套属性和方法。

3.递归复制:如果对象有嵌套属性或方法,深拷贝会递归复制嵌套对象的属性和方法。

4.不受原对象改变影响:因为深拷贝生成的对象完全独立,所以它不会受到原对象的更改的影响。

需要注意的是,深拷贝可能会导致性能问题,特别是当数据结构非常复杂时。因为深拷贝会复制所有的属性和方法,包括对象的嵌套属性和方法,所以可能需要花费大量的时间和内存来完成。


今天的分享到这里就结束了,感谢大家支持,创作不易,希望大家能给博主个三连



目录
相关文章
|
6月前
|
设计模式 存储 Java
深拷贝与浅拷贝,就是这么简单
深拷贝与浅拷贝,就是这么简单
|
存储 Cloud Native Linux
C++ 深拷贝浅拷贝
C++ 深拷贝浅拷贝
|
JSON Java API
深拷贝、浅拷贝
深拷贝、浅拷贝
81 0
|
JavaScript 前端开发 Python
故事会【深拷贝和浅拷贝】
故事会【深拷贝和浅拷贝】
|
1月前
|
JavaScript 前端开发 Java
什么是深拷贝,什么是浅拷贝
什么是深拷贝,什么是浅拷贝
48 0
|
4月前
|
编译器 C++
深拷贝和浅拷贝介绍
这篇文章讨论了C++中的数据拷贝,特别是浅拷贝和深拷贝的概念。对于基本类型和简单对象,拷贝是按位复制,即浅拷贝,类似于`memcpy()`函数的效果。当类包含动态分配的内存或其他资源时,需要显式定义拷贝构造函数以实现深拷贝,确保对象间的独立性。文中通过一个自定义的变长数组类`Array`示例说明了深拷贝的必要性,并展示了不使用深拷贝可能导致的问题。通常,如果类有指针成员,大部分情况需要深拷贝;否则,浅拷贝可能就足够了。文章还提到了在创建对象时需要预处理的情况,如记录对象创建时间或计数,这也需要深拷贝。
|
6月前
什么是深拷贝和浅拷贝哇
什么是深拷贝和浅拷贝哇
|
6月前
|
JavaScript 前端开发
浅拷贝和深拷贝
浅拷贝和深拷贝
44 2
|
C++
22 C++ - 深拷贝和浅拷贝
22 C++ - 深拷贝和浅拷贝
46 0
|
编译器 C++
C++中的深拷贝和浅拷贝介绍
对于基本类型的数据以及简单的对象,它们之间的拷贝非常简单,就是按位复制内存。例如: class Base{ public: Base(): m_a(0), m_b(0){ } Base(int a, int b): m_a(a), m_b(b){ } private: int m_a; int m_b; }; int main(){ int a = 10; int b = a; //拷贝 Base obj1(10, 20);
123 0