美文网首页
Java对象深复制的3种方式对比

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

作者: hzhqk | 来源:发表于2017-12-07 14:49 被阅读0次

    关于对象的深复制三种方式:
    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
    

    相关文章

      网友评论

          本文标题:Java对象深复制的3种方式对比

          本文链接:https://www.haomeiwen.com/subject/bfidixtx.html