你作为一个Java领域的专家,请完成以下任务:clone, 深拷贝浅拷贝
时间: 2023-08-12 18:05:32 浏览: 40
1. Clone
在Java中,对象的克隆是通过`clone()`方法实现的。`clone()`方法是一个native方法,它会在内存中复制一份对象,并返回这份复制的副本。需要注意的是,`clone()`方法只会复制对象的值,而不会复制对象的引用。因此,当我们改变克隆对象中引用类型的属性时,原对象中的对应属性也会被改变。
```
public class Person implements Cloneable {
private String name;
private int age;
private List<String> hobbies;
public Person(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
this.hobbies = hobbies;
}
@Override
public Person clone() throws CloneNotSupportedException {
Person clone = (Person) super.clone();
clone.hobbies = new ArrayList<>(this.hobbies);
return clone;
}
}
```
在上面的代码中,我们实现了`Person`类的克隆方法。首先,我们通过调用`super.clone()`方法复制了对象的值,然后对`hobbies`属性进行了深拷贝,以避免改变克隆对象中的引用类型属性导致原对象中的属性被改变。
2. 深拷贝与浅拷贝
深拷贝和浅拷贝是对于对象中引用类型属性的复制方式而言的。
浅拷贝只会复制对象的值和引用,而不会复制引用指向的对象。例如:
```
public class Person implements Cloneable {
private String name;
private int age;
private List<String> hobbies;
public Person(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
this.hobbies = hobbies;
}
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
}
List<String> hobbies = new ArrayList<>();
hobbies.add("reading");
Person p1 = new Person("Tom", 20, hobbies);
Person p2 = p1.clone();
p2.getHobbies().add("swimming");
System.out.println(p1.getHobbies()); // [reading, swimming]
System.out.println(p2.getHobbies()); // [reading, swimming]
```
在上面的代码中,我们创建了两个`Person`对象,`p1`和`p2`,并将它们的`hobbies`属性都设置为`[reading]`。然后,我们通过调用`p1.clone()`方法复制了`p1`对象,得到了`p2`对象。接着,我们向`p2`对象的`hobbies`属性中添加了一个新元素`swimming`。最后,输出`p1`和`p2`对象的`hobbies`属性,发现它们的值都变成了`[reading, swimming]`。这是因为`p1`和`p2`对象的`hobbies`属性引用的是同一个对象。
而深拷贝则会复制引用指向的对象。例如:
```
public class Person implements Cloneable {
private String name;
private int age;
private List<String> hobbies;
public Person(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
this.hobbies = hobbies;
}
@Override
public Person clone() throws CloneNotSupportedException {
Person clone = (Person) super.clone();
clone.hobbies = new ArrayList<>(this.hobbies);
return clone;
}
}
List<String> hobbies = new ArrayList<>();
hobbies.add("reading");
Person p1 = new Person("Tom", 20, hobbies);
Person p2 = p1.clone();
p2.getHobbies().add("swimming");
System.out.println(p1.getHobbies()); // [reading]
System.out.println(p2.getHobbies()); // [reading, swimming]
```
在上面的代码中,我们同样创建了两个`Person`对象,`p1`和`p2`,并将它们的`hobbies`属性都设置为`[reading]`。然后,我们通过调用`p1.clone()`方法复制了`p1`对象,得到了`p2`对象。接着,我们向`p2`对象的`hobbies`属性中添加了一个新元素`swimming`。最后,输出`p1`和`p2`对象的`hobbies`属性,发现它们的值分别为`[reading]`和`[reading, swimming]`。这是因为`p1`对象和`p2`对象的`hobbies`属性引用的是不同的对象。