<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么不建議使用 Java 自帶的序列化?

          共 5956字,需瀏覽 12分鐘

           ·

          2021-06-12 11:30


          作者:rickiyang
          出處:www.cnblogs.com/rickiyang/p/11074232.html

          談到序列化我們自然想到 Java 提供的 Serializable 接口,在 Java 中我們?nèi)绻枰蛄谢恍枰^承該接口就可以通過輸入輸出流進(jìn)行序列化和反序列化。

          但是在提供很用戶簡單的調(diào)用的同時他也存在很多問題:

          1、無法跨語言

          當(dāng)我們進(jìn)行跨應(yīng)用之間的服務(wù)調(diào)用的時候如果另外一個應(yīng)用使用c語言來開發(fā),這個時候我們發(fā)送過去的序列化對象,別人是無法進(jìn)行反序列化的因為其內(nèi)部實現(xiàn)對于別人來說完全就是黑盒。

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

          這個我們可以做一個實驗還是上一節(jié)中的Message類,我們分別用java的序列化和使用二進(jìn)制編碼來做一個對比,下面我寫了一個測試類:

          @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("使用二進(jìn)制序列化的長度:"+result.length);

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

          輸出結(jié)果為:

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

          3、序列化效率

          這個我們也可以做一個對比,還是上面寫的測試代碼我們循環(huán)跑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("使用二進(jìn)制序列化的長度:"+result.length);*/
                  }
                  long endTime1 = System.currentTimeMillis();
                  System.out.println("使用二進(jìn)制序列化100000次耗時:" +(endTime1 - startTime1));

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

          結(jié)果為:

          結(jié)果為毫秒數(shù),這個差距也是不小的。

          結(jié)合以上我們看到:

          目前的序列化過程中使用 Java 本身的肯定是不行,使用二進(jìn)制編碼的話又的我們自己去手寫,所以為了讓我們少搬磚前輩們早已經(jīng)寫好了工具讓我們調(diào)用,目前社區(qū)比較活躍的有 google 的 Protobuf 和 Apache 的 Thrift。

          1、Intellij IDEA這樣 配置注釋模板,讓你瞬間高出一個逼格!
          2、吊炸天的 Docker 圖形化工具 Portainer,必須推薦給你!
          3、最牛逼的 Java 日志框架,性能無敵,橫掃所有對手!
          4、把Redis當(dāng)作隊列來用,真的合適嗎?
          5、驚呆了,Spring Boot居然這么耗內(nèi)存!你知道嗎?
          6、全網(wǎng)最全 Java 日志框架適配方案!還有誰不會?
          7、Spring中毒太深,離開Spring我居然連最基本的接口都不會寫了

          點分享

          點收藏

          點點贊

          點在看

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  波多野结衣精品在线 | 狠狠撸天天干 | 麻豆国产一区 | 色就是色setufree | 日本特级 黄 色 片 |