java 深拷贝和浅拷贝的区别
时间: 2024-01-13 22:02:45 浏览: 85
Java中的对象赋值和拷贝有两种方式:深拷贝和浅拷贝。
浅拷贝是指将一个对象复制到另一个对象,两个对象共享相同的内存地址,即它们指向同一块内存区域。当原始对象发生变化时,复制的对象也会随之改变。
深拷贝是指将一个对象复制到另一个对象,两个对象拥有不同的内存地址,即它们指向不同的内存区域。当原始对象发生变化时,复制的对象不会受到影响。
Java语言中,通常通过实现Cloneable接口和重写clone()方法来实现深拷贝和浅拷贝。
实现浅拷贝的方法很简单,只需要使用Object类的clone()方法即可。例如:
```
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
```
使用clone()方法实现浅拷贝:
```
Person p1 = new Person("Tom", 20);
Person p2 = (Person) p1.clone();
System.out.println(p1 == p2); // false
System.out.println(p1.getName() == p2.getName()); // true
```
从上面的代码可以看出,p1和p2虽然指向不同的内存地址,但是它们的name属性指向同一块内存区域,因此p1.getName() == p2.getName()的结果为true。
实现深拷贝的方法相对复杂一些,需要将对象中的所有引用类型属性也进行拷贝。例如:
```
public class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
person.address = (Address) address.clone();
return person;
}
}
public class Address implements Cloneable {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
```
使用clone()方法实现深拷贝:
```
Person p1 = new Person("Tom", 20, new Address("Beijing", "Chaoyang"));
Person p2 = (Person) p1.clone();
System.out.println(p1 == p2); // false
System.out.println(p1.getAddress() == p2.getAddress()); // false
```
从上面的代码可以看出,p1和p2不仅指向不同的内存地址,它们的address属性也指向不同的内存区域,因此p1.getAddress() == p2.getAddress()的结果为false。
阅读全文