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