2020.4.26更新
json序列化是可以包含類型信息的,拿阿里的fastjson舉例:
JSON.toJSONString(t, SerializerFeature.WriteClassName)
序列化一個Long型整數(shù),結(jié)果是999L而不是999。但是這樣不能跨語言了。
??很多工具例如Spring封裝的RedisTemplate還有Kafka等,默認(rèn)使用的序列化方法都是JdkSerializationRedisSerializer,而一般我們都要修改成Jackson2JsonRedisSerializer或者FastJsonRedisSerializer。一是序列化之后體積小,而是可以跨語言。
??我們以使用fastjson為例說明為什么比jdk序列化的體積?。ㄋ衘son序列化方式的序列化結(jié)果都是一樣的)。
序列化一個類:
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,里面的內(nèi)容:
?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結(jié)構(gòu)類似的對象,而jdk序列化則是記錄了JavaBean的類型以及JavaBean屬性的類型。也因為如此,json序列化天然具有跨語言特性。