把Json转换成数组很简单,只需要用TypeToken转化一下就可以了
fun main(){ val list = mutableListOf(Bean(0, "123"), Bean(1, "456")) val json = list.toJson() val type = object :TypeToken
>(){}.type val newList = Gson().fromJson
>(json,type) newList.forEach { println(it) }}fun Any.toJson(): String = Gson().toJson(this)data class Bean( val code:Int, val msg:String)复制代码
运行结果如下:
但是如果有很多不同的类需要转换,那么每次都需要写TypeToken就显得很麻烦。所以很自然的就会想到用泛型实现。 代码如下:
funString.toBeanList():List = Gson().fromJson(this,object:TypeToken
>(){}.type)复制代码
main方法如下:
fun main(){ val list = mutableListOf(Bean(0, "123"), Bean(1, "456")) val json = list.toJson() json.toBeanList().forEach { println(it) }}复制代码
很显然,运行结果报错了。Gson不支持泛型解析:
可以从报错结果看到,在把LinkedTreeMap转换为Bean的过程中出错了,LinkedTreeMap是Gson库内部数据模型,换句话说我们的解析失败了,说明Gson解析时不支持泛型。
但是,我们可以用ParameterizedType 来实现。 ParameterizedTypeImpl类如下:
class ParameterizedTypeImpl(val clz: Class<*>) : ParameterizedType { override fun getRawType(): Type = List::class.java override fun getOwnerType(): Type? = null override fun getActualTypeArguments(): Array= arrayOf(clz)}复制代码
main方法如下:
funString.toBeanList(clazz: Class<*>): List = Gson().fromJson
>(this, ParameterizedTypeImpl(clazz))fun Any.toJson(): String = Gson().toJson(this)fun main() { val list = mutableListOf(Bean(0, "123"), Bean(1, "456")) val json = list.toJson() json.toBeanList (Bean::class.java).forEach { println(it) }}复制代码
结果:
最后结果是成功了,但是每次还需要传入class,很是麻烦。所以kotlin的reified关键字就排上用场了。 再次修改方法如下:
//重点inline funString.toBeanList(): List = Gson().fromJson
>(this, ParameterizedTypeImpl(T::class.java))fun Any.toJson(): String = Gson().toJson(this)fun main() { val list = mutableListOf(Bean(0, "123"), Bean(1, "456")) val json = list.toJson() json.toBeanList ().forEach { println(it) }}复制代码
完美运行: