天天看點

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

談到序列化我們自然想到 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 自帶的序列化?
@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 自帶的序列化?