Gson文字列配列をListオブジェクトに変換(汎用、Kotlin)

3306 ワード

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
)


実行結果は次のとおりです.
しかし、変換が必要なクラスがたくさんあると、そのたびにType Tokenを書くのは面倒になります.だから自然に汎用で実現したいと思っています.コードは次のとおりです.
fun  String.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で実現できる.ParameterizedType Implクラスは次のとおりです.
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メソッドは次のとおりです.
fun  String.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のrefiedキーワードが役に立ちました.再修正方法は次のとおりです.
//  
inline fun  String.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)
    }
}

完全な運用:
転載先:https://juejin.im/post/5cd3dc23e51d453ae54a2064