有两种方式:

    1). 实现Cloneable接口并重写Object类中的clone()方法;

    2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下;

    1. import java.io.ByteArrayInputStream;
    2. import java.io.ByteArrayOutputStream;
    3. import java.io.ObjectInputStream;
    4. import java.io.ObjectOutputStream;
    5. import java.io.Serializable;
    6. public class MyUtil {
    7. private MyUtil() {
    8. throw new AssertionError();
    9. }
    10. @SuppressWarnings("unchecked")
    11. public static <T extends Serializable> T clone(T obj) throws Exception {
    12. ByteArrayOutputStream bout = new ByteArrayOutputStream();
    13. ObjectOutputStream oos = new ObjectOutputStream(bout);
    14. oos.writeObject(obj);
    15. ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
    16. ObjectInputStream ois = new ObjectInputStream(bin);
    17. return (T) ois.readObject();
    18. // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
    19. // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
    20. }
    21. }

    注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是好过把问题留到运行时。