深拷贝和浅拷贝区别

深拷贝和浅拷贝区别

在 Java 中,**深拷贝(Deep Copy)和浅拷贝(Shallow Copy)**是指对象复制时,复制的方式和结果的不同。理解这两者的区别非常重要,特别是在处理复杂对象时。浅拷贝和深拷贝的主要区别在于对象内部引用的处理方式。

1. 浅拷贝(Shallow Copy)

浅拷贝是指复制对象时,只复制对象本身,而不会复制对象内部引用的其他对象。也就是说,源对象和目标对象内部的引用类型变量(如数组、对象等)指向相同的内存地址(即它们引用的是相同的对象)。因此,源对象和目标对象共享同一份数据。

浅拷贝的特点:

复制的是对象的“引用”,而非对象所指向的数据。

对象的引用类型字段仍然指向原始对象的内存地址(即浅拷贝并没有创建新的引用对象)。

浅拷贝的代码示例:

class Address {

String city;

Address(String city) {

this.city = city;

}

}

class Person {

String name;

Address address;

Person(String name, Address address) {

this.name = name;

this.address = address;

}

// 浅拷贝方法

public Person shallowCopy() {

return new Person(this.name, this.address); // 复制的是引用,address 地址相同

}

}

public class ShallowCopyExample {

public static void main(String[] args) {

Address address = new Address("New York");

Person person1 = new Person("Alice", address);

// 浅拷贝

Person person2 = person1.shallowCopy();

System.out.println(person1.name); // 输出: Alice

System.out.println(person2.name); // 输出: Alice

System.out.println(person1.address.city); // 输出: New York

System.out.println(person2.address.city); // 输出: New York

// 修改 person2 的 address

person2.address.city = "Los Angeles";

// 由于浅拷贝,person1 和 person2 的 address 是同一个对象

System.out.println(person1.address.city); // 输出: Los Angeles

System.out.println(person2.address.city); // 输出: Los Angeles

}

}

输出结果:

Alice

Alice

New York

New York

Los Angeles

Los Angeles

说明:

person1 和 person2 的 address 引用指向相同的 Address 对象,因此修改 person2 的 address 会影响 person1 的 address。

这是因为我们进行了浅拷贝,address 字段只是引用了相同的内存地址。

2. 深拷贝(Deep Copy)

深拷贝是指复制对象时,不仅复制对象本身,而且复制对象内部引用的其他对象。也就是说,深拷贝会创建对象及其所引用的所有对象的副本,源对象和目标对象之间完全独立,它们不会共享任何引用对象。

深拷贝的特点:

复制的是对象及其所有引用的对象,确保新对象的所有引用都指向新创建的对象。

目标对象与源对象在内存中完全独立,修改目标对象的属性不会影响源对象。

深拷贝的代码示例:

class Address {

String city;

Address(String city) {

this.city = city;

}

// 深拷贝方法

public Address deepCopy() {

return new Address(this.city); // 创建一个新的 Address 对象

}

}

class Person {

String name;

Address address;

Person(String name, Address address) {

this.name = name;

this.address = address;

}

// 深拷贝方法

public Person deepCopy() {

// 创建新的 Person 对象,并对 address 进行深拷贝

return new Person(this.name, this.address.deepCopy());

}

}

public class DeepCopyExample {

public static void main(String[] args) {

Address address = new Address("New York");

Person person1 = new Person("Alice", address);

// 深拷贝

Person person2 = person1.deepCopy();

System.out.println(person1.name); // 输出: Alice

System.out.println(person2.name); // 输出: Alice

System.out.println(person1.address.city); // 输出: New York

System.out.println(person2.address.city); // 输出: New York

// 修改 person2 的 address

person2.address.city = "Los Angeles";

// 由于深拷贝,person1 和 person2 的 address 是不同的对象

System.out.println(person1.address.city); // 输出: New York

System.out.println(person2.address.city); // 输出: Los Angeles

}

}

输出结果:

Alice

Alice

New York

New York

New York

Los Angeles

说明:

person1 和 person2 的 address 引用指向不同的对象,person2 修改 address 不会影响 person1。

这是因为我们进行了深拷贝,address 字段指向了新创建的 Address 对象。

3. 深拷贝与浅拷贝的对比

特性

浅拷贝(Shallow Copy)深拷贝(Deep Copy)

引用对象的处理

只复制对象本身,不复制对象引用的其他对象。

复制对象本身及其所有引用的对象,确保每个引用指向新的对象。

对象之间的关系

源对象和目标对象共享相同的引用对象。

源对象和目标对象独立,互不影响。

修改影响

修改目标对象会影响源对象,因为它们共享同一引用对象。

修改目标对象不会影响源对象,因为它们不共享任何引用对象。

性能

浅拷贝比深拷贝更高效,因为只涉及对象本身和引用的复制。

深拷贝需要复制整个对象图,性能开销较大。

4. 深拷贝和浅拷贝的实际应用

浅拷贝:

适用于不修改对象内部引用的情况下。比如,你只需要复制对象的基本数据,且不关心对象引用类型字段的变化。

常见场景:复制对象用于某些不改变内部引用的操作,如在多线程中共享不可变的对象。

深拷贝:

适用于需要复制对象及其引用对象,且这些引用对象的状态不应该被共享的场景。例如,修改一个对象的内部引用数据时不希望影响到其他对象。

常见场景:当对象中包含嵌套的可变对象时,深拷贝能确保每个对象都被独立复制,防止修改一个对象影响到其他对象。

相关故事

小米mix3 滑盖设置在哪
365365bet

小米mix3 滑盖设置在哪

微信怎么查看是否购买理财产品?
365bet体育在线中文

微信怎么查看是否购买理财产品?

台湾偶像剧10大童星今昔对比照曝光谁的变化大
365365bet

台湾偶像剧10大童星今昔对比照曝光谁的变化大