Java工具类之对象拷贝

引言

在Java开发中,经常会遇到需要复制对象的情况。对象拷贝(Object Copy)是指将一个对象的值复制到另一个对象中,使得两个对象拥有相同的属性值,但是互不影响。Java提供了多种方式来实现对象拷贝,本文将介绍一些常用的方法和工具类。

浅拷贝和深拷贝

在进行对象拷贝时,有两种常见的方式:浅拷贝和深拷贝。

浅拷贝

浅拷贝是指只复制对象的引用,而不复制对象本身。也就是说,拷贝后的对象与原对象共享内部对象的引用。当原对象发生变化时,拷贝对象也会相应地发生变化。

深拷贝

深拷贝是指复制对象本身以及其所有引用的对象,而不仅仅是复制引用。拷贝后的对象与原对象互相独立,彼此之间的修改不会相互影响。

常用的对象拷贝方法

1. 手动拷贝

最简单的方式就是手动拷贝对象的属性。如果对象的属性较少,手动拷贝是一个可行的方式。下面是一个示例代码:

public class Person {
    private String name;
    private int age;

    // 构造方法、Getter和Setter省略

    public Person copy() {
        Person person = new Person();
        person.setName(this.name);
        person.setAge(this.age);
        return person;
    }
}

2. Cloneable接口

Java提供了Cloneable接口来支持对象的拷贝。需要注意的是,Cloneable接口只是一个标记接口,并没有定义任何方法。为了实现深拷贝,需要重写Object类的clone()方法并在其中复制对象的属性。

public class Person implements Cloneable {
    private String name;
    private int age;

    // 构造方法、Getter和Setter省略

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

通过调用clone()方法,可以实现对象的浅拷贝。如果要实现深拷贝,还需要在clone()方法中对引用类型的属性进行复制。

public class Person implements Cloneable {
    private String name;
    private int age;
    private Address address;

    // 构造方法、Getter和Setter省略

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.setAddress((Address) this.address.clone());
        return person;
    }
}

3. 序列化和反序列化

Java中的序列化和反序列化可以实现对象的深拷贝。通过将对象写入输出流,然后再从输入流中读取对象,可以得到一个新的对象。

public class Person implements Serializable {
    private String name;
    private int age;

    // 构造方法、Getter和Setter省略

    public Person copy() 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();
    }
}

上述代码中,通过将对象写入ByteArrayOutputStream,再从ByteArrayInputStream中读取对象,实现了对象的深拷贝。

对象拷贝工具类

为了方便地进行对象拷贝,可以将上述的方法封装到一个工具类中。下面是一个简单的对象拷贝工具类:

public class ObjectCopyUtils {
    public static <T extends Serializable> T copy(T source) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(source);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (T) ois.readObject();
    }
}

使用该工具类,可以在任何需要对象拷贝的地方直接调用copy方法。例如:

Person