Özel bir sınıftan genel tür listesi alamıyorum (Dönüşler):
val turnsType = TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson(pref.turns, turnsType)
o dedi:
cannot access '<init>' it is 'public /*package*/' in 'TypeToken'
Özel bir sınıftan genel tür listesi alamıyorum (Dönüşler):
val turnsType = TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson(pref.turns, turnsType)
o dedi:
cannot access '<init>' it is 'public /*package*/' in 'TypeToken'
Yanıtlar:
Bu satır içi eğlenceyi yaratın:
inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)
ve sonra şu şekilde çağırabilirsiniz:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Önceki Alternatifler:
ALTERNATİF 1:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
Koymanız object :
ve belirli bir türü girmeniz gerekirfromJson<List<Turns>>
ALTERNATİF 2:
@Cypressious'un bahsettiği gibi, bu şekilde de başarılabilir:
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
olarak kullan:
val turnsType = genericType<List<Turns>>()
Bu sorunu çözer:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
İlk satır, aşağı inen bir nesne ifadesi yaratır TypeToken
ve ardından Java'yı bundan alır Type
. Daha sonra Gson().fromJson
yöntem, işlevin sonucu için belirtilen türe ihtiyaç duyar ( TypeToken
oluşturulanla eşleşmelidir ). Bu çalışmanın iki versiyonu, yukarıdaki gibi veya:
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
Oluşturmayı kolaylaştırmak için TypeToken
, reified tür parametrelerini kullanabilmesi için satır içi olması gereken bir yardımcı işlev oluşturabilirsiniz :
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
Hangisi daha sonra aşağıdaki yollardan biriyle kullanılabilir:
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
Ve tüm süreç, Gson
örnek için bir uzantı işlevine sarılabilir :
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
Böylece Gson'ı arayabilir ve hiç endişelenmeyebilirsiniz TypeToken
:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Burada Kotlin, atamanın bir tarafından veya diğer tarafından tür çıkarımını kullanıyor ve bir satır içi işlevin tam türü ( TypeToken
silinmeden) geçmesi için yeniden biçimlendirilmiş jenerikler kullanıyor ve bunu kullanarak bir a oluşturmak ve ayrıca Gson'a çağrı yapmak
Gson().fromJson<kotlin.List<Turns>>(pref.turns)
Gson()
yoksa statikmiş Gson
gibi mi? İlkine ihtiyacınız var, bir örneğe.
Başka bir seçenek (diğerlerinden daha zarif göründüğünden emin değil) şöyle bir çağrı olabilir:
turns = Gson().fromJson(allPurchasesString, Array<Turns>::class.java).toMutableList()
Yani "saf Kotlin" yerine java Array sınıfını tek satırlık kullanıyorsunuz.
Ben dönüştürmek için böyle bir şey kullanılmış T
etmek string
ve String
geri T
kullanarak Gson
. Tam olarak aradığınız şey değil ama her ihtimale karşı.
Uzantı bildirme
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)
Kullanım
// 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
}
}
Bu da işe yarar ve daha basittir
inline fun <reified T> Gson.fromJson(json: String) : T =
this.fromJson<T>(json, T::class.java)
generic reified function
Gson'dan Kotlin , ArrayList<T>
bu kodu kullanmak için seriyi kaldırıyor
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