Java对象深复制的3种方式对比

2017-12-07  本文已影响0人  hzhqk

关于对象的深复制三种方式:
1、new Instance,即自己new对象一一赋值属性,写起来繁琐;
2、继承Cloneable方式,比较推荐,原生&快速;
3、序列化&反序列化方式(实现Serializable或Externalizable),耗时但是实现简易,功能强大。

import java.io.*;

/**
 * Created by hqk2015@foxmail.com on 2017/12/07.
 */
public class Copy implements Cloneable,Serializable {
    private String str;
    private Obj obj;

    public Copy() {
    }

    private Copy(Obj obj) throws CloneNotSupportedException {
        this.obj = (Obj) obj.clone();
    }
    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }
    public Obj getObj() {
        return obj;
    }

    public void setObj(Obj obj) {
        this.obj = obj;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Copy copy = new Copy(this.obj);
        copy.setStr(this.str);
        return copy;
    }

    public Object serializeClone() throws IOException, ClassNotFoundException {
        // 将对象写到流里
        OutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(this);
        // 从流里读出来
        InputStream bi = new ByteArrayInputStream(((ByteArrayOutputStream) bo).toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        //close stream
        return (oi.readObject());
    }

    public Copy newClone() {
        Copy copy = new Copy();
        copy.setObj(this.obj.newClone());
        copy.setStr(this.str);
        return copy;
    }

    public static void main(String[] args) throws Exception {
        Copy origin = new Copy();
        origin.setStr("str");
        origin.setObj(new Obj("field:obj"));
        int loop = 10000;
        //Cloneable方式
        long start = System.currentTimeMillis();
        for (int i = 0; i < loop; i++) {
            origin.clone();
        }
        long end = System.currentTimeMillis();
        long test1 = end - start;
        //序列化&反序列化方式
        start = System.currentTimeMillis();
        for (int i = 0; i < loop; i++) {
            origin.serializeClone();
        }
        end = System.currentTimeMillis();
        long test2 = end - start;
        //new Instance实例属性复制方式
        start = System.currentTimeMillis();
        for (int i = 0; i < loop; i++) {
//            BeanUtils.cloneBean(origin);
            origin.newClone();
        }
        end = System.currentTimeMillis();
        long test3 = end - start;
        System.out.println("Cloneable方式: " + test1
                + "ms\n序列化方式: " + test2
                + "ms\nnew Instance方式: " + test3 + "ms");
    }
}
class Obj implements Cloneable,Serializable{
    private String str;

    public Obj() {
    }

    public Obj(String str) {
        this.str = str;
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

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

    public Obj newClone() {
        Obj obj = new Obj();
        obj.setStr(this.str);
        return obj;
    }
}

用IntelliJ IDEA多次测试,总体来说,耗时: 序列化 > new Instance > Cloneable
以下是10批次(每批次10000次执行)运行结果:

    Cloneable方式  | 序列化方式 | new Instance方式
    ———————————————|————————————|——————————————————————————————
            7      |     1457   |       20
            7      |     1627   |       5
            7      |     1469   |       5
            7      |     1584   |       74
            13     |     1478   |       6
            7      |     1411   |       7
            6      |     1530   |       8
            7      |     1494   |       17
            7      |     1528   |       5
            6      |     1486   |       44
    ————————————————————————————————————————————————————————————
  平均(ms):7.4    |    1506.4 |       19.1
上一篇下一篇

猜你喜欢

热点阅读