前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么老程序员从不使用 Java 自带的序列化?

为什么老程序员从不使用 Java 自带的序列化?

作者头像
业余草
发布2021-12-06 17:10:17
2320
发布2021-12-06 17:10:17
举报
文章被收录于专栏:业余草

谈到序列化我们自然想到 Java 提供的 Serializable 接口,在 Java 中我们如果需要序列化只需要继承该接口就可以通过输入输出流进行序列化和反序列化。

「但是在提供很用户简单的调用的同时他也存在很多问题:」

无法跨语言

当我们进行跨应用之间的服务调用的时候如果另外一个应用使用 c 语言来开发,这个时候我们发送过去的序列化对象,别人是无法进行反序列化的因为其内部实现对于别人来说完全就是黑盒。

序列化之后的码流太大

这个我们可以做一个实验还是上一节中的 Message 类,我们分别用 java 的序列化和使用二进制编码来做一个对比,下面我写了一个测试类:

代码语言:javascript
复制
@Test  
public void testSerializable(){  
    String str = "哈哈,我是一条消息";  
    Message msg = new Message((byte)0xAD,35,str);  
    ByteArrayOutputStream out = new ByteArrayOutputStream();  
    try {  
        ObjectOutputStream os = new ObjectOutputStream(out);  
        os.writeObject(msg);  
        os.flush();  
        byte[] b = out.toByteArray();  
        System.out.println("jdk序列化后的长度: "+b.length);  
        os.close();  
        out.close();

        ByteBuffer buffer = ByteBuffer.allocate(1024);  
        byte[] bt = msg.getMsgBody().getBytes();  
        buffer.put(msg.getType());  
        buffer.putInt(msg.getLength());  
        buffer.put(bt);  
        buffer.flip();

        byte[] result = new byte[buffer.remaining()];  
        buffer.get(result);  
        System.out.println("使用二进制序列化的长度:"+result.length);

    } catch (IOException e) {  
        e.printStackTrace();  
    }  
}

输出结果为:

我们可以看到差距是挺大的,目前的主流编解码框架序列化之后的码流也都比 java 序列化要小太多。

序列化效率

这个我们也可以做一个对比,还是上面写的测试代码我们循环跑 100000 次对比一下时间:

代码语言:javascript
复制
@Test  
public void testSerializable(){  
    String str = "哈哈,我是一条消息";  
    Message msg = new Message((byte)0xAD,35,str);  
    ByteArrayOutputStream out = new ByteArrayOutputStream();  
    try {  
        long startTime = System.currentTimeMillis();  
        for(int i = 0;i < 100000;i++){  
            ObjectOutputStream os = new ObjectOutputStream(out);  
            os.writeObject(msg);  
            os.flush();  
            byte[] b = out.toByteArray();  
            /*System.out.println("jdk序列化后的长度: "+b.length);*/  
            os.close();  
            out.close();  
        }  
        long endTime = System.currentTimeMillis();  
        System.out.println("jdk序列化100000次耗时:" +(endTime - startTime));

        long startTime1 = System.currentTimeMillis();  
        for(int i = 0;i < 100000;i++){  
            ByteBuffer buffer = ByteBuffer.allocate(1024);  
            byte[] bt = msg.getMsgBody().getBytes();  
            buffer.put(msg.getType());  
            buffer.putInt(msg.getLength());  
            buffer.put(bt);  
            buffer.flip();

            byte[] result = new byte[buffer.remaining()];  
            buffer.get(result);  
            /*System.out.println("使用二进制序列化的长度:"+result.length);*/  
        }  
        long endTime1 = System.currentTimeMillis();  
        System.out.println("使用二进制序列化100000次耗时:" +(endTime1 - startTime1));

    } catch (IOException e) {  
        e.printStackTrace();  
    }  
}

结果为:

结果为毫秒数,这个差距也是不小的。

总结

目前的序列化过程中使用 Java 本身的肯定是不行,使用二进制编码的话又的我们自己去手写,所以为了让我们少搬砖前辈们早已经写好了工具让我们调用,目前社区比较活跃的有 google 的 Protobuf 和 Apache 的 Thrift。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/06/25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 无法跨语言
  • 序列化之后的码流太大
  • 序列化效率
  • 总结
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档