Java序列化与反序列化Json通常会使用Gson
和Jackson
这两个框架,之前因为公司都是用的Gson
也没太在意。最近碰到了一个这两框架在反序列化上有些不太一样的地方。
通常在Java中我们反序列化一个Json字符串是,如果我们不想定义一个具体的类,我们会把它反序列化为Java中的Map类,这时候我们其实没有提供任何Map中的value的类型的信息,序列化框架需要自己根据json字符串来判断应该反序列化为哪个类。这里我发现Gson
在处理数字的反序列化,会默认都反序列化成Double
,而Jackson
则可以智能的判断。
为什么会产生这样的差异?查阅源码以后我发现,这两个框架在对JsonToken的定义上就存在差异。
|
|
|
|
可以看到,Jackson
在JsonToken中就将数字定义成两种类型VALUE_NUMBER_INT
和VALUE_NUMBER_FLOAT
,而Gson中只有一种NUMBER
。
事实上这两个框架在解析数字时都区分了整型和浮点型,代码可以参见
Gson中JsonReader的peekNumber()方法
Jackson中ReaderBasedJsonParser的_parsePosNumber()方法
但是Gson
在将其转成JsonToken时将PEEKED_LONG
和PEEKED_NUMBER
统一返回成了JsonToken.NUMBER
可以参见JsonReader中的peek()函数
|
|
而上层在反序列化时是以JsonToken为类型的参考依据的(当用户没有提供类型信息时),比如我们可以看ObjectTypeAdapter
(通常我们不给类型,gson就会按Object类型来反序列化)中的反序列化
|
|
综上所述,gson其实是可以做到识别整型和浮点型,但是在上层隐藏了这个信息,不知道是出于什么考虑。