您的位置:

Java工程师必备:深入掌握Object.clone方法

Object类中的clone()方法是Java中的一个重要方法,这个方法可以返回一个对象的“浅拷贝”,也就是对原对象中的内容进行复制,但不会复制原对象指向的对象。深入掌握这个方法,将对Java工程师的职业发展带来很大帮助。

一、clone()方法的使用和作用

clone()方法的作用是生成一个与原对象相同的新对象。使用clone()方法时,需要实现Cloneable接口,否则会抛出CloneNotSupportedException异常。

以下是使用clone方法实现浅拷贝的示例:

class Person implements Cloneable{
    private String name;
    private int age;
    private ArrayList skills;
 
    public Person(String name, int age, ArrayList
    skills) {
        this.name = name;
        this.age = age;
        this.skills = skills;
    }
 
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
 
public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        ArrayList
     skills = new ArrayList();
        skills.add("Java");
        skills.add("Spring");
        Person person = new Person("Tom", 23, skills);
        Person cloned = (Person) person.clone();
 
        System.out.println(person == cloned); //false
        System.out.println(person.getName() == cloned.getName()); //true
        System.out.println(person.getSkills() == cloned.getSkills()); //true
    }
}

    
   
  

从输出的结果可以看到,浅拷贝后,原对象和新对象指向的ArrayList对象是一个,但是Person对象不是同一个。

二、浅拷贝和深拷贝的区别

浅拷贝

clone()方法实现的是浅拷贝,也就是说,如果对象的属性是基本类型或不可变类型,可以实现一个副本,不影响原对象。但如果属性是可变对象,如ArrayList,浅拷贝只会拷贝引用,而不会将ArrayList中的值也进行拷贝,使得原对象与新对象的引用相同。

深拷贝

深拷贝则是对可变对象进行递归拷贝,最终生成一个新的对象,使得原对象与新对象没有任何关系,可以互不干扰。

以下是深拷贝的示例:

public class Person implements Cloneable {
    private String name;
    private int age;
    private ArrayList skills;
 
    public Person(String name, int age, ArrayList
    skills) {
        this.name = name;
        this.age = age;
        this.skills = skills;
    }
 
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.skills = (ArrayList
    ) this.skills.clone();
        return cloned;
    }
    //省略访问器
}
 
public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        ArrayList
      skills = new ArrayList();
        skills.add("Java");
        skills.add("Spring");
        Person person = new Person("Tom", 23, skills);
        Person cloned = (Person) person.clone();
 
        System.out.println(person == cloned); //false
        System.out.println(person.getSkills() == cloned.getSkills()); //false
    }
}

     
    
   
  

从输出结果中,可以看出原对象与克隆对象没有任何关系,拥有自己独立的ArrayList对象。

三、实现clone()方法需要注意的细节

1、需要实现Cloneable接口

在使用clone()方法之前,需要实现Cloneable接口,否则会抛出CloneNotSupportedException异常。

2、需要重写clone()方法

重写clone()方法时,需要注意clone()方法是protected类型,需要使用public类型覆盖这个方法,并且要调用super.clone()方法来得到一个新的实例。返回的对象必须向下转型为正确的类型。

3、注意引用对象的问题

如果被克隆对象有引用类型的属性时,可以通过new一个新的对象进行深拷贝。

除此之外,还可以使用序列化实现深度拷贝,在序列化后再反序列化得到一个新的对象。

四、总结

深入掌握Object.clone()方法,能够让我们更好的处理对象克隆时的问题,从而提高Java工程师的职业发展水平。越来越多的框架和库要求我们实现cloneable接口,因此,掌握clone()方法将对我们的工作带来帮助。