序列化
protobuf
- 结构化数据存储格式(json,xml等)
- 高性能编解码技术
- 语言和平台无关,扩展性好
- 支持java,C++,Python三种语言
优点:无需静态编译,但序列化前需预先传入schema
缺点:不支持无默认构造函数的类,反序列化时需用户自己初始化序列化后的对象,其只负责将该对象进行赋值
thrift
- 支持多种语言(C++,C#,Cocoa,Erlag,Haskell,java,Ocami,Perl,PHP,Python,Ruby,和SmallTalk)
- 适用了组建大型数据交换及存储工具,对于大型系统中的内部数据传输,相对于json和xml在性能上和传输大小上都有明显的优势。
- 支持三种比较典型的编码方式。(通用二进制编码,压缩二进制编码,优化的可选字段压缩编解码)
kryo
优点:速度快,序列化后体积小
缺点:跨语言支持较复杂
hessian
优点:默认支持跨语言
缺点:较慢
public byte[] serialize(Object obj) {
Hessian2Output hos;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
hos = new Hessian2Output(bos);
hos.writeObject(obj);
hos.flush();
return bos.toByteArray();
} catch (IOException e) {
}
return null;
}
public <T> T deserialize(byte[] bytes) {
ByteArrayInputStream bis;
try {
bis = new ByteArrayInputStream(bytes);
Hessian2Input his = new Hessian2Input(bis);
return (T) his.readObject();
} catch (IOException e) {
}
return null;
}
fst
优点:fst是完全兼容JDK序列化协议的系列化框架,序列化速度大概是JDK的4-10倍,大小是JDK大小的1/3左右
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>2.04</version>
</dependency>
private static FSTConfiguration configuration = FSTConfiguration.createStructConfiguration();
public static byte[] serialize(Object obj) {
return configuration.asByteArray(obj);
}
public static <T> T deserialize(byte[] bytes) {
return (T)configuration.asObject(bytes);
}
json
java
- 无法跨语言。这应该是java序列化最致命的问题了。由于java序列化是java内部私有的协议,其他语言不支持,导致别的语言无法反序列化,这严重阻碍了它的应用。
- 序列后的码流太大。java序列化的大小是二进制编码的5倍多!
- 序列化性能太低。java序列化的性能只有二进制编码的6.17倍,可见java序列化性能实在太差了。
public static byte[] serialize(Object obj) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);) {
oos.writeObject(obj);
return baos.toByteArray();
} catch (IOException e) {
}
return null;
}
public static <T> T deserialize(byte[] bytes) {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);) {
return (T)ois.readObject();
} catch (Exception e) {
}
return null;
}
Objenesis不使用构造方法创建Java对象
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>3.0.1</version>
</dependency>
public class T {
private String id = "T";
private String name;
public T(String name) {
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public static void main(String[] args) {
// 第一种方式
try {
T t0 = T.class.newInstance();
System.out.println(t0.getId());
} catch (Exception e) {
System.err.println("没有无参构造方法,无法实例化,抛异常");
}
// 第二种方式,不使用构造方法,对象以非标准的方式被动态实例化
Objenesis objenesis = new ObjenesisStd();
T t1 = objenesis.newInstance(T.class);
// 属性的默认值获取不到
System.out.println(t1.getId());
// null
}
}