📅  最后修改于: 2023-12-03 15:02:01.968000             🧑  作者: Mango
在Java中,可以使用clone()
方法对对象进行浅拷贝或深拷贝。在属性较多并且创建对象较为耗时时,我们可以使用clone()
方法对现有的对象进行复制操作,以达到节省时间和提高效率的目的。在这篇文章中,我们就来介绍一下Java中的属性clone()
方法及其示例。
clone()
方法clone()
方法是一个本地方法,被用来创建当前对象的副本。这个方法在Object类中声明为:
protected native Object clone() throws CloneNotSupportedException;
从这里我们可以看出,clone()
方法返回的是一个Object类型的副本对象,需要注意的是,如果要使用clone()
方法复制一个对象,该对象的类必须实现Cloneable接口。如果没有实现该接口,会抛出一个CloneNotSupportedException异常。
clone()
方法为了使用clone()
方法,我们需要注意以下两点:
clone()
方法并将访问修饰符改为publicpublic 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 int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
如上代码所示,我们在Person类中实现了Cloneable接口,并对clone()
方法进行了覆盖,将访问修饰符改为了public。
在默认情况下,使用clone()
方法进行拷贝时,是浅拷贝。即如果当前对象中有引用类型的属性,那么拷贝出来的对象和当前对象将引用同一个对象。这时候,如果我们要进行深拷贝,那么我们就需要在覆盖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;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public List<String> getHobbies(){
return hobbies;
}
public void setHobbies(List<String> hobbies){
this.hobbies = hobbies;
}
@Override
public Object clone() throws CloneNotSupportedException {
Person clonePerson = (Person) super.clone();
clonePerson.hobbies = new ArrayList<>(this.hobbies);
return clonePerson;
}
}
如上代码所示,我们在Person类中新增了一个List类型的属性hobbies,并在重写clone()
方法中,手动创建一个新的ArrayList对象,并将当前对象的hobbies属性复制到该新对象中,从而实现了深拷贝。
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("zhangsan", 20, new ArrayList<>(Arrays.asList("swimming", "music")));
System.out.println("原始对象:" + person1.getName() + "," + person1.getAge() + "," + person1.getHobbies());
Person person2 = (Person) person1.clone();
System.out.println("克隆对象:" + person2.getName() + "," + person2.getAge() + "," + person2.getHobbies());
person2.setName("lisi");
person2.getHobbies().add("reading");
System.out.println("修改后的克隆对象:" + person2.getName() + "," + person2.getAge() + "," + person2.getHobbies());
System.out.println("未修改的原始对象:" + person1.getName() + "," + person1.getAge() + "," + person1.getHobbies());
}
如上代码所示,我们在main方法中创建了一个Person对象,并调用clone()
方法进行拷贝。之后,我们修改了拷贝出来的对象,并输出原始对象和克隆对象的信息,以及修改后的克隆对象和未修改的原始对象的信息。代码输出如下:
原始对象:zhangsan,20,[swimming, music]
克隆对象:zhangsan,20,[swimming, music]
修改后的克隆对象:lisi,20,[swimming, music, reading]
未修改的原始对象:zhangsan,20,[swimming, music]
从结果可以看出,拷贝出来的对象和原始对象的属性值相同,但是在对拷贝出来的对象进行修改后,原始对象的属性值并没有发生变化,从而验证了clone()
方法的正确性。
在Java中,使用clone()
方法可以方便地对对象进行复制操作,实现拷贝的效果。但需要注意的是,浅拷贝和深拷贝的区别,在复制引用类型的属性时,需要手动创建新的对象并复制到该新对象中才能实现深拷贝。