移動互聯(lián)網(wǎng)用戶基數(shù)越來越大,除了一些工具類(指南針、手電筒等)的應(yīng)用,絕大部分APP都需要與后端進行交互。
交互的數(shù)據(jù)格式有JSON、XML等,由于JSON具有語法簡單、占用空間小等優(yōu)勢,基本所有的公司都以它來進行數(shù)據(jù)交互。
在交互中間,就會遇到JSON 數(shù)據(jù)和JavaBean 對象之間的相互轉(zhuǎn)換問題,比如{"age":11,"name":"David","gender":"woman"}這個JSON 串往往需要轉(zhuǎn)換成Person 對象。
在項目中,我們基本不會自己寫這部分代碼,因為有一些類似于Gson、Jackson 的框架已經(jīng)做了這部分工作,它們可以很簡單的實現(xiàn)JSON 串與JavaBean 對象之間的相互轉(zhuǎn)換。但是了解其實現(xiàn)的原理及涉及到的一些概念,如反射,對我們了解其他框架甚至自己寫框架都是有幫助的。
下面,主要介紹下JSON 數(shù)據(jù)如何轉(zhuǎn)換為JavaBean 對象及相關(guān)的一些概念。主要用到了反射、泛型兩個技術(shù)點,了解了這兩個概念,很容易能搞懂這個原理,并且能初探一些框架的實現(xiàn)原理。
1、什么是反射?
Java 的反射機制是在程序運行期間而不是在編譯期間,可以獲取某個類的所有方法和屬性,可以通過反射的方式進行對象的實例化,能夠調(diào)用對象的每一個方法,可以通過調(diào)用方法或者直接對屬性進行賦值。
它使得Java 這種編譯性語言有了某些動態(tài)語言的特性,極大的增強了程序設(shè)計的靈活性,但也會帶來點性能的問題(其實也不是個大問題,相對帶來的方便,根本不用考慮)。它是構(gòu)建框架的基礎(chǔ)所在,最著名的SSH 集成框架底層實現(xiàn)用到了很多反射機制,可以很靈活的把一些信息放在配置文件中,減少了很大的代碼量。
如Spring 的核心機制:依賴注入,就利用了反射來實例化類中的一些屬性,達到了控制反轉(zhuǎn)的目的;Struts 利用反射,根據(jù)表單中的數(shù)據(jù)對Action 中的對象進行實例化和對屬性進行賦值,具體的應(yīng)該是調(diào)用set 方法;Mybatis、Hibernate 也利用反射把數(shù)據(jù)庫查詢結(jié)果集實例化成JavaBean 對象。
反射相關(guān)的類都在java.lang.reflect 包中。
2、什么是泛型
泛型是JDK1.5開始提供的,它實現(xiàn)了“參數(shù)化類型”的概念,可以提高程序的可讀性和穩(wěn)定性,并且所有的強制轉(zhuǎn)換都是自動和隱式的,提高了代碼的重用率。相對比較安全,比如可以在運行期避免發(fā)生java.lang.ClassCastException異常。
上圖中紅框圈主的地方就用到了泛型,而且是用在了集合類中,當然還可以使用在方法和接口中,分別稱為泛型類、泛型方法及泛型接口,這里就不一一說明了。
3、如何轉(zhuǎn)換?
實現(xiàn)方法參考以下代碼即可,注釋的比較詳細,還是比較簡單的。
代碼中集合對象的解析相對復(fù)雜一些,參考以下代碼,其實就是用了個迭代。
小結(jié)
以上代碼中的數(shù)據(jù)類型不夠完全,比如還會遇到屬性是復(fù)雜對象、Date、Enum、Map 之類的,也可以通過其它的辦法來進行轉(zhuǎn)化,比如根據(jù)對象的屬性進行一一賦值。
可以從https://github.com/StarKeyMan/JsonToObject.git下載代碼進行完善。
本文作者:宋亞偉(點融黑幫),現(xiàn)任點融網(wǎng)北京團隊Android開發(fā)工程師,工作4年,愛好乒乓球和游泳。