回答:
このインラインの楽しみを作成します。
inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)
そして、あなたはこのようにそれを呼び出すことができます:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
以前の選択肢:
代替案1:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
object :
特定のタイプを入れなければなりませんfromJson<List<Turns>>
代替案2:
@cypressiousが言及するように、これは次の方法でも達成できます。
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
使用:
val turnsType = genericType<List<Turns>>()
これは問題を解決します:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
1行目は、子孫のオブジェクト式を作成し、そこからTypeToken
Java Type
を取得します。次に、Gson().fromJson
メソッドには、関数の結果に指定されたタイプが必要です(TypeToken
作成されたものと一致する必要があります)。上記のように、または次のようにこの2つのバージョンが機能します。
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
作成を簡単にするTypeToken
ために、ヘルパー関数を作成できます。ヘルパー関数は、インライン化して、具体化された型パラメーターを使用できるようにする必要があります。
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
これらは、次のいずれかの方法で使用できます。
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
そして、プロセス全体をGson
インスタンスの拡張関数にラップすることができます:
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
したがって、Gsonを呼び出すだけで、心配する必要はありませんTypeToken
。
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
ここでKotlinは、割り当ての一方または他方からの型推論を使用しており、インライン関数のジェネリックTypeToken
を具体化して(消去なしで)完全な型を通過させ、それを使用してを構築し、Gsonを呼び出します
Gson().fromJson<kotlin.List<Turns>>(pref.turns)
Gson()
か、それともGson
静的な場合と同じですか?最初のインスタンスが必要です。
別のオプション(他のオプションよりもエレガントに見えるかどうかはわかりません)は、次のような呼び出しです。
turns = Gson().fromJson(allPurchasesString, Array<Turns>::class.java).toMutableList()
したがって、「純粋なKotlin」の代わりにjava Arrayクラスの1つのライナーを使用しています。
私は、変換するために、このようなものを使用T
するstring
&String
バックにT
使用しましたGson
。正確にあなたが探しているものではなく、念のために。
拡張の宣言
inline fun <reified T : Any> T.json(): String = Gson().toJson(this, T::class.java)
inline fun <reified T : Any> String.fromJson(): T = Gson().fromJson(this,T::class.java)
使用法
// Passing an object to new Fragment
companion object {
private const val ARG_SHOP = "arg-shop"
@JvmStatic
fun newInstance(shop: Shop) =
ShopInfoFragment().apply {
arguments = Bundle().apply {
putString(ARG_SHOP, shop.json())
}
}
}
// Parsing the passed argument
private lateinit var shop: Shop
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
shop = it.getString(ARG_SHOP).fromJson() ?: return
}
}
これも機能し、より簡単です
inline fun <reified T> Gson.fromJson(json: String) : T =
this.fromJson<T>(json, T::class.java)
generic reified function
GsonのKotlin は、ArrayList<T>
このコードを使用するために逆シリアル化します
inline fun <reified T> get( ... ): ArrayList<T>{
val str = "[{},{}]"
val type = TypeToken.getParameterized(ArrayList::class.java, T::class.java).type
val t = Gson().fromJson<ArrayList<T>>(str, type)
return t
}
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type