关于java:为什么不建议使用-Java-自带的序列化

41次阅读

共计 2373 个字符,预计需要花费 6 分钟才能阅读完成。

作者:rickiyang

出处:www.cnblogs.com/rickiyang/p/11074232.html

谈到序列化咱们天然想到 Java 提供的 Serializable 接口,在 Java 中咱们如果须要序列化只须要继承该接口就能够通过输入输出流进行序列化和反序列化。

然而在提供很用户简略的调用的同时他也存在很多问题:

1、无奈跨语言

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

2、序列化之后的码流太大

这个咱们能够做一个试验还是上一节中的 Message 类,咱们别离用 java 的序列化和应用二进制编码来做一个比照,上面我写了一个测试类:

@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 序列化要小太多。

3、序列化效率

这个咱们也能够做一个比照,还是下面写的测试代码咱们循环跑 100000 次比照一下工夫:

@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。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2021 最新版)

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0