Gson与FastJson比较
一. 簡介和優(yōu)劣
1.Google的Gson
Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來,但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應(yīng)用。Gson的應(yīng)用主要為toJson與fromJson兩個轉(zhuǎn)換函數(shù),無依賴,不需要例外額外的jar,能夠直接跑在JDK上。
而在使用這種對象轉(zhuǎn)換之前需先創(chuàng)建好對象的類型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對應(yīng)的對象。
類里面只要有g(shù)et和set方法,Gson完全可以將復(fù)雜類型的json到bean或bean到j(luò)son的轉(zhuǎn)換,是JSON解析的神器。
Gson在功能上面無可挑剔,但是性能上面比FastJson有所差距。
2.阿里巴巴的FastJson
Fastjson是一個Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發(fā)。
無依賴,不需要例外額外的jar,能夠直接跑在JDK上。 FastJson在復(fù)雜類型的Bean轉(zhuǎn)換Json上會出現(xiàn)一些問題,可能會出現(xiàn)引用的類型,導(dǎo)致Json轉(zhuǎn)換出錯,需要制定引用。
FastJson采用獨(dú)創(chuàng)的算法,將parse的速度提升到極致,超過所有json庫。
3. 其他
json-lib最開始的也是應(yīng)用最廣泛的json解析工具,json-lib 不好的地方確實(shí)是依賴于很多第三方包,對于復(fù)雜類型的轉(zhuǎn)換,json-lib對于json轉(zhuǎn)換成bean還有缺陷,比如一個類里面會出現(xiàn)另一個類的list或者map集合,json-lib從json到bean的轉(zhuǎn)換就會出現(xiàn)問題。json-lib在功能和性能上面都不能滿足現(xiàn)在互聯(lián)網(wǎng)化的需求。
相比json-lib框架,Jackson所依賴的jar包較少,簡單易用并且性能也要相對高些。
而且Jackson社區(qū)相對比較活躍,更新速度也比較快。
Jackson對于復(fù)雜類型的json轉(zhuǎn)換bean會出現(xiàn)問題,一些集合Map,List的轉(zhuǎn)換出現(xiàn)問題。
Jackson對于復(fù)雜類型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式
綜上,在項(xiàng)目選型的時候可以使用Google的Gson和阿里巴巴的FastJson兩種并行使用,
如果只是功能要求,沒有性能要求,可以使用google的Gson,
如果有性能上面的要求可以使用Gson將bean轉(zhuǎn)換json確保數(shù)據(jù)的正確,使用FastJson將Json轉(zhuǎn)換Bean。
二、基本使用方式
Gson
//解成對象 Fromat mFromat = new Gson().fromJson(jsonStringObject, Fromat.class);//解成對象組 LinkedList<Fromat> list = new LinkedList<MainActivity.Fromat>(); Type type = new TypeToken<LinkedList<Fromat>>(){}.getType(); list = new Gson().fromJson(jsonStringArray, type);//泛型統(tǒng)一封裝時 需要傳個 type 進(jìn)來 new TypeToken<LinkedList<Fromat>>(){}.getType(); fromJson(String json, Type typeOfT) public <T> T fromJson(String json, Type typeOfT)fastJson
//解析成對象 Fromat fastjsonObject = JSON.parseObject(jsonObjectString, Fromat.class);//解析成對象組 List<Fromat> fastjsonArray = JSON.parseArray(jsonArrayString, Fromat.class);//泛型統(tǒng)一封裝時 需要傳個 type 進(jìn)來 或者TypeReference 也可以也是調(diào)用的type new TypeReference<Fromat>() {} new TypeReference<Fromat>() {}.getType() public static <T> T parseObject(String input, Type clazz, Feature... features) public static <T> T parseObject(String text, TypeReference<T> type, Feature... features)三、細(xì)節(jié)比較
1、屬性和set方法名稱不一致時
現(xiàn)在我有這么一個Bean,屬性名為firstName,但是它的set方法卻是setName(),而不是setFirstName()
下面我使用Gson與FastJson分別將這樣的一個Bean轉(zhuǎn)成一個Json字符串,大家猜會有什么區(qū)別?
輸出結(jié)果:
fastJson={"age":24,"name":"扎巴也"} gson={"firstName":"扎巴也","age":24}序列化時fastJson是按照set方法的名字來轉(zhuǎn)換的,而gson則是按照屬性的名字來轉(zhuǎn)換的。
不信?好,我們再來看看反序列化時會怎樣?
@Testpublic void fromJson() {String json = "{\"age\":24,\"name\":\"扎巴也\"}";Bean fastjson = JSON.parseObject(json, Bean.class);System.out.println("fastJson=" + fastjson.toString());Bean gson = new Gson().fromJson(json, Bean.class);System.out.println("gson=" + gson.toString());}輸出結(jié)果:
fastJson=Bean{firstName='扎巴也', age=24} gson=Bean{firstName='null', age=24}因?yàn)锽ean類里面有name的set方法,所以fastJson解析時調(diào)用了setName,所以firstName有值
但是Bean類里面卻沒有name屬性,所以gson解析時,firstName沒有值
2、有屬性,無set方法
現(xiàn)在我有這么一個Person,屬性名為name,但是它沒有name的set方法
那么,我來解析這樣一個字符串時,FastJson和Gson會有什么區(qū)別呢?
測試代碼:
@Testpublic void fromJsonNoSet() {String json = "{\"age\":24,\"name\":\"扎巴也\"}";Person fastjson = JSON.parseObject(json, Person.class);System.out.println("fastJson=" + fastjson.toString());Person gson = new Gson().fromJson(json, Person.class);System.out.println("gson=" + gson.toString());}輸出結(jié)果:
fastJson=Person{name='null', age=24} gson=Person{name='扎巴也', age=24}因?yàn)镻erson沒有name的set方法,所以fastJson解析的name為null
再次證明,fastJson是按照set方法的名字來轉(zhuǎn)換的,而gson則是按照屬性的名字來轉(zhuǎn)換的。
那么,無屬性,有set方法時,兩者有什么區(qū)別呢?(其實(shí)沒有屬性的話,set方法調(diào)用了沒啥作用)
測試代碼:
輸出結(jié)果:
調(diào)用了setName:扎巴也 fastJson=Student{age=24} gson=Student{age=24}fastJson調(diào)用了set方法,而gson沒有調(diào)用set方法。
同樣證明,fastJson是按照set方法的名字來轉(zhuǎn)換的,而gson則是按照屬性的名字來轉(zhuǎn)換的。
3、無默認(rèn)的無參構(gòu)造方法
現(xiàn)在有這么一個Teacher類,他只有一個兩個參數(shù)的構(gòu)造方法,沒有默認(rèn)的無參構(gòu)造方法,那么,我來解析這樣一個字符串時,FastJson和Gson會有什么區(qū)別呢?
{"age":24,"name":"扎巴也"}測試代碼:
@Testpublic void fromJsonNoDefaultConstructor() {String json = "{\"age\":24,\"name\":\"扎巴也\"}";Teacher gson = new Gson().fromJson(json, Teacher.class);System.out.println("gson=" + gson.toString());Teacher fastjson = JSON.parseObject(json, Teacher.class);System.out.println("fastJson=" + fastjson.toString());}這里,Gson可以正常的解析,但是,fastJson則會報(bào)錯,因?yàn)闆]有默認(rèn)的無參構(gòu)造方法。
這說明了反序列化時,fastJson是通過無參構(gòu)造方法來創(chuàng)建對象的,那么gson又是怎么創(chuàng)建對象的呢?(是調(diào)用了Unsafe.allocateInstance()這個native方法來創(chuàng)建對象的。
但是,我們知道,這個方法直接操作內(nèi)存,是不安全的,那么,如果反序列化的那個類,存在默認(rèn)的無參構(gòu)造方法呢?)
4、有默認(rèn)的無參構(gòu)造方法
@Testpublic void fromJsonHasDefaultConstructor() {String json = "{\"age\":24,\"name\":\"扎巴也\"}";Boss gson = new Gson().fromJson(json, Boss.class);System.out.println("gson=" + gson.toString());Boss fastjson = JSON.parseObject(json, Boss.class);System.out.println("fastJson=" + fastjson.toString());}gson和fastJson都調(diào)用了默認(rèn)的無參構(gòu)造方法.
至此,我們可以得出結(jié)論:
有默認(rèn)的無參構(gòu)造方法時,gson和fastJson都會調(diào)用它來創(chuàng)建對象,沒有默認(rèn)的無參構(gòu)造方法時,fastJson會直接報(bào)錯!而gson則會調(diào)用Unsafe.allocateInstance()這個native方法直接在內(nèi)存上創(chuàng)建對象。
四、Gson中使用泛型
例:JSON字符串?dāng)?shù)組
當(dāng)我們要通過Gson解析這個json時,一般有兩種方式:使用數(shù)組,使用List。而List對于增刪都是比較方便的,所以實(shí)際使用是還是List比較多。
數(shù)組比較簡單
Gson gson = new Gson(); String jsonArray = "[\"Android\",\"Java\",\"PHP\"]"; String[] strings = gson.fromJson(jsonArray, String[].class);但對于List將上面的代碼中的 String[].class 直接改為 List.class 是行不通的。對于Java來說List 和List 這倆個的字節(jié)碼文件只一個那就是List.class,這是Java泛型使用時要注意的問題 泛型擦除。
為了解決的上面的問題,Gson為我們提供了TypeToken來實(shí)現(xiàn)對泛型的支持,所以當(dāng)我們希望使用將以上的數(shù)據(jù)解析為List時需要這樣寫。
Gson gson = new Gson(); String jsonArray = "[\"Android\",\"Java\",\"PHP\"]"; String[] strings = gson.fromJson(jsonArray, String[].class); List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());注:TypeToken的構(gòu)造方法是protected修飾的,所以上面才會寫成new TypeToken<List>() {}.getType() 而不是 new TypeToken<List>().getType()
參考:
https://www.jianshu.com/p/e740196225a4
https://blog.csdn.net/lckj686/article/details/51587073
https://blog.csdn.net/xiaoke815/article/details/52920405
https://www.jianshu.com/p/153111dde324
轉(zhuǎn)載于:https://www.cnblogs.com/john8169/p/9780516.html
總結(jié)
以上是生活随笔為你收集整理的Gson与FastJson比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 2009 求数列的和
- 下一篇: synchronized关键字原理