大家都在说嫌弃java原生序列化,今天聊聊它到底是因为哪些原因导致大家嫌弃的。
首先,序列化详细讲解的可以参考下:java序列化详解
java的序列化缺点如下:
一、无法跨语言
通过Java的原生Serializable
接口与ObjectOutputStream
实现的序列化,只有java语言自己能通过ObjectInputStream
来解码,其他语言,如C
、C++
、Python
等等,都无法对其实现解码。
二、序列化码流太大
简单做个对比,一个是java原生序列化,一个是通用的二进制编码
User对象
:
import java.io.Serializable;
import java.nio.ByteBuffer;
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte[] codeC() {
ByteBuffer buffer = ByteBuffer.allocate(1024);
byte[] value = this.name.getBytes();
buffer.putInt(value.length);
buffer.put(value);
buffer.putLong(this.id);
buffer.flip();
byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
}
Main方法
:
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
public class Main {
public static void main(String[] args) throws Exception {
UserInfo info = new UserInfo();
info.setId(1L);
info.setName("Tom");
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
out.writeObject(info);
out.flush();
out.close();
byte[] b = bout.toByteArray();
System.out.println("the jdk serializable len is : " + b.length);
bout.close();
System.out.println("the byte array serializable len is : " + info.codeC().length);
}
}
测试结果
the jdk serializable len is : 191
the byte array serializable len is : 15
Process finished with exit code 0
可以看到差距是相当的明显了。
三、序列时间太慢
改一下codeC
方法:
public byte[] codeC(ByteBuffer buffer) {
buffer.clear();
byte[] value = this.name.getBytes();
buffer.putInt(value.length);
buffer.put(value);
buffer.putLong(this.id);
buffer.flip();
byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
Main方法
:
package com.xhban.netty.serialize;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
public class Main {
public static void main(String[] args) throws Exception {
UserInfo info = new UserInfo();
info.setId(1L);
info.setName("Tom");
int loop = 100_0000;
ByteArrayOutputStream bout = null;
ObjectOutputStream out = null;
long start = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
bout = new ByteArrayOutputStream();
out = new ObjectOutputStream(bout);
out.flush();
out.close();
byte[] b = bout.toByteArray();
bout.close();
}
System.out.println("the jdk serializable cost time : " + (System.currentTimeMillis() - start) + " ms");
System.out.println("------------------------------");
start = System.currentTimeMillis();
ByteBuffer buffer = ByteBuffer.allocate(1024);
for (int i = 0; i < loop; i++) {
byte[] bytes = info.codeC(buffer);
}
System.out.println("the byte array serializable cost time : " + (System.currentTimeMillis() - start) + " ms");
}
}
测试结果
:
the jdk serializable cost time : 522 ms
------------------------------
the byte array serializable cost time : 88 ms
这个差距也是相当的明显了。
以上便是java原生序列化的缺点了