2020.4.26更新
json序列化是可以包含类型信息的,拿阿里的fastjson举例:
JSON.toJSONString(t, SerializerFeature.WriteClassName)
序列化一个Long型整数,结果是999L
而不是999。但是这样不能跨语言了。
很多工具例如Spring封装的RedisTemplate还有Kafka等,默认使用的序列化方法都是JdkSerializationRedisSerializer,而一般我们都要修改成Jackson2JsonRedisSerializer或者FastJsonRedisSerializer。一是序列化之后体积小,而是可以跨语言。
我们以使用fastjson为例说明为什么比jdk序列化的体积小(所有json序列化方式的序列化结果都是一样的)。
序列化一个类:
import java.io.Serializable;
public class TestObj implements Serializable {
private String param1;
private Long param2;
public TestObj() {
}
public TestObj(String param1, Long param2) {
this.param1 = param1;
this.param2 = param2;
}
public String getParam1() {
return param1;
}
public void setParam1(String param1) {
this.param1 = param1;
}
public Long getParam2() {
return param2;
}
public void setParam2(Long param2) {
this.param2 = param2;
}
@Override
public String toString() {
return "TestObj{" +
"param1='" + param1 + '\'' +
", param2=" + param2 +
'}';
}
}
使用jdk序列化:
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class TestJdkSerializer {
public static void main(String[] args) {
String fileName = "D:\\video\\aaa.txt";
TestObj obj = new TestObj("aaa", 99999L);
try (FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeBytes("asdqwe");
} catch (Exception e) {
e.printStackTrace();
}
}
}
打开文件D:\\video\\aaa.txt
,里面的内容:
�sr �com.example.demo.TestObj?0�$搝 � �L �param1t �Ljava/lang/String;L �param2t �Ljava/lang/Long;xpt �aaasr �java.lang.Long;嬩愄?? �J �valuexr �java.lang.Number啲?�斷? xp �啛
使用fastjson序列化:
import com.alibaba.fastjson.JSON;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class TestJdkSerializer {
public static void main(String[] args) {
TestObj obj = new TestObj("aaa", 99999L);
System.out.println(JSON.toJSONString(obj));
}
}
输出:
{"param1":"aaa","param2":"99999"}
可以简单的这么理解,fastjson序列化与反序列是通过json符号组合一个与JavaBean结构类似的对象,而jdk序列化则是记录了JavaBean的类型以及JavaBean属性的类型。也因为如此,json序列化天然具有跨语言特性。