深入理解Java中的克隆攻略
在Java中,对象的克隆可分为浅拷贝和深拷贝两类,深拷贝是创建一个新的对象,将原始对象所有的属性都复制到新对象中,新对象与原始对象互不干扰;浅拷贝则是创建一个新的对象,但是将原始对象中的基本类型的值和引用类型的指针都复制到新对象中,两者共享引用类型的数据,修改其中一个对象会影响另外一个对象。
对象的克隆方式
Java中对象的克隆方式有两种:实现Cloneable接口+重写clone()方法和实现Serializable接口+通过对象序列化和反序列化实现克隆。
实现Cloneable接口+重写clone()方法
首先需要实现Cloneable接口,这个接口并没有任何方法,只是起到一个标识的作用,表示该类是可克隆的,然后重写clone()方法,返回一个克隆对象。需要注意的是,重写的clone()方法要使用访问权限为public的修饰符,否则无法调用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 person = (Person) super.clone();
person.hobbies = new ArrayList<>(this.hobbies);
return person;
}
}
在这个示例中,Person类实现了Cloneable接口,并且重写了clone()方法。在clone()方法中,调用了Object类的clone()方法,得到一个浅拷贝对象,然后再对hobbies属性做深拷贝。
实现Serializable接口+通过对象序列化和反序列化实现克隆
另一种克隆方式是通过对象序列化和反序列化实现克隆。需要实现Serializable接口,这个接口的作用是将对象转换为字节序列,以便于传输或保存到文件中。使用这种方式进行克隆,需要将对象序列化成字节流,然后将字节流转化为对象,得到一个新的克隆对象。
示例代码:
public class Person implements Serializable {
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 Person clone() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Person) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
在这个示例中,Person类实现了Serializable接口,并且定义了一个clone()方法,通过将对象序列化为字节流,然后反序列化得到新的对象实现克隆。
总结
Java中对象克隆方式有两种,实现Cloneable接口+重写clone()方法和实现Serializable接口+通过对象序列化和反序列化实现克隆。需要注意的是,使用浅拷贝时,修改原始对象中引用类型属性的值会影响克隆对象的属性值,而使用深拷贝则可以避免这个问题。因此,使用Java中的克隆需根据需要选择合适的方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Java中的克隆 - Python技术站