Java6 复制对象
复制对象在Java编程中经常会遇到的需求之一。在Java6及以后的版本中,提供了多种方式来实现对象的复制。本文将介绍几种常用的复制对象的方法,并给出相应的代码示例。
1. 浅拷贝
浅拷贝是指只复制对象中的基本类型数据和引用,而不复制引用的对象本身。在Java中,可以通过实现Cloneable
接口和重写clone()
方法来实现浅拷贝。
class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
}
在上述代码中,Person
类实现了Cloneable
接口,并重写了clone()
方法。通过调用clone()
方法可以实现对Person
对象的浅拷贝。
Person person1 = new Person("Alice", 20);
Person person2 = null;
try {
person2 = person1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
上述代码实现了person1
对象的浅拷贝,将结果赋值给person2
。
2. 深拷贝
与浅拷贝不同,深拷贝会递归地复制对象中的所有引用对象,而不仅仅是引用本身。在Java中,可以通过序列化和反序列化来实现深拷贝。
import java.io.*;
class Address implements Serializable {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
public void setCity(String city) {
this.city = city;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public String getStreet() {
return street;
}
}
class Person implements Serializable {
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 void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Address getAddress() {
return address;
}
public Person deepClone() throws IOException, ClassNotFoundException {
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();
}
}
在上述代码中,Person
类和Address
类都实现了Serializable
接口,通过序列化和反序列化可以实现对Person
对象的深拷贝。
Person person1 = new Person("Alice", 20, new Address("CityA", "StreetA"));
Person person2 = null;
try {
person2 = person1.deepClone();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
上述代码实现了person1
对象的深拷贝,将结果赋值给person2
。
3. Apache Commons BeanUtils
除了上述两种方式,还可以使用第三方库Apache Commons BeanUtils来实现对象的复制。Apache Commons BeanUtils提供了一个BeanUtils
类,其中的copyProperties()
方法可以实现对象之间的属性复制。
import org.apache.commons.beanutils.BeanUtils;
class Address {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
public void setCity(String city) {
this.city = city;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity()