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()