返回

赋值、浅拷贝、深拷贝大PK

前端

相信不少程序员朋友们在日常开发中都会经常接触到赋值、浅拷贝、深拷贝的概念,甚至在面试时也会经常被问及它们之间的区别。浅拷贝和深拷贝虽然听起来都和拷贝相关,但这两者之间却是存在着天壤之别,这可能也是面试官会经常问及这两个问题的原因之一。

针对面试官可能会询问到的相关问题,本文将通过全面解析赋值、浅拷贝、深拷贝这三个概念,帮助大家详细了解它们各自的特点和区别,让你在面试中轻松应对相关问题。

正文

1. 赋值:一次简单的变量引用

赋值本质上就是将变量的引用指向另一个变量或者对象,这种方式并不会创建新的对象或变量,也不会复制对象的内容。当我们对一个被赋值变量进行操作时,实际操作的是原变量,这意味着被赋值变量所指向的对象也将受到影响。

举个例子:

int a = 10;
int b = a;

a = 20;

System.out.println(a); // 20
System.out.println(b); // 10

在这个例子中,我们先将变量a的值赋给了变量b,然后将变量a的值更改为20。可以看到,虽然变量b的值没有被显式地更改,但它仍然受到变量a的影响,这是因为变量b实际上只是指向了变量a,当变量a的值发生变化时,变量b的值也会相应地改变。

2. 浅拷贝:只复制对象的引用,不复制对象的内容

浅拷贝是一种比较特殊的赋值方式,它会复制对象的部分属性,但不会复制对象的所有属性。浅拷贝只复制对象的引用,而不会复制对象的内容。这意味着浅拷贝后的对象与原对象共享相同的内存地址。

举个例子:

class Person {
    private String name;
    private int age;
}

Person p1 = new Person();
p1.setName("Alice");
p1.setAge(20);

Person p2 = p1; // 浅拷贝

p1.setName("Bob");

System.out.println(p1.getName()); // Bob
System.out.println(p2.getName()); // Bob

在这个例子中,我们先创建了一个Person对象p1并对其进行初始化,然后将p1的引用赋给另一个Person对象p2。此时,p1和p2指向了同一个Person对象。当我们通过p1更改Person对象的名字时,p2的名字也会相应地改变,因为它们都指向了同一个对象。

3. 深拷贝:复制对象的所有属性,包括对象的内容

深拷贝与浅拷贝不同,它会复制对象的所有属性,包括对象的内容。这意味着深拷贝后的对象与原对象在内存中是独立的,它们不会共享相同的内存地址。

举个例子:

class Person {
    private String name;
    private int age;

    public Person(Person other) {
        this.name = other.name;
        this.age = other.age;
    }
}

Person p1 = new Person();
p1.setName("Alice");
p1.setAge(20);

Person p2 = new Person(p1); // 深拷贝

p1.setName("Bob");

System.out.println(p1.getName()); // Bob
System.out.println(p2.getName()); // Alice

在这个例子中,我们先创建了一个Person对象p1并对其进行初始化,然后通过调用Person类的构造函数来创建另一个Person对象p2,并将p1作为参数传递给构造函数。这样,p2就成为了p1的深拷贝。当我们通过p1更改Person对象的名字时,p2的名字不会受到影响,因为它们是独立的对象。

总结

通过对赋值、浅拷贝、深拷贝这三个概念的全面解析,我们可以总结出以下几点:

  • 赋值只是将变量的引用指向另一个变量或对象,不会创建新的对象或变量,也不会复制对象的内容。
  • 浅拷贝只复制对象的引用,不复制对象的内容,浅拷贝后的对象与原对象共享相同的内存地址。
  • 深拷贝复制对象的所有属性,包括对象的内容,深拷贝后的对象与原对象在内存中是独立的,它们不会共享相同的内存地址。

希望通过本文的讲解,大家能够对赋值、浅拷贝、深拷贝这三个概念有一个更加清晰的认识,并在面试中能够轻松应对相关问题。