Tôi không thể nhận Danh sách loại chung từ một lớp tùy chỉnh (Lượt):
val turnsType = TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson(pref.turns, turnsType)
nó nói rằng:
cannot access '<init>' it is 'public /*package*/' in 'TypeToken'
Tôi không thể nhận Danh sách loại chung từ một lớp tùy chỉnh (Lượt):
val turnsType = TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson(pref.turns, turnsType)
nó nói rằng:
cannot access '<init>' it is 'public /*package*/' in 'TypeToken'
Câu trả lời:
Tạo niềm vui nội tuyến này:
inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)
và sau đó bạn có thể gọi nó theo cách này:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Các lựa chọn thay thế trước đó:
ĐẠI SỐ 1:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
Bạn phải đặt object :và loại cụ thể trongfromJson<List<Turns>>
ĐẠI SỐ 2:
Như @cypressious đã đề cập, nó cũng có thể đạt được theo cách này:
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
sử dụng như là:
val turnsType = genericType<List<Turns>>()
Điều này giải quyết vấn đề:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
Dòng đầu tiên tạo một biểu thức đối tượng giảm dần TypeTokenvà sau đó lấy Java Typetừ đó. Sau đó, Gson().fromJsonphương thức cần kiểu được chỉ định cho kết quả của hàm (phải khớp với kiểu TypeTokenđược tạo). Hai phiên bản của tác phẩm này, như trên hoặc:
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
Để tạo dễ dàng hơn, TypeTokenbạn có thể tạo một hàm trợ giúp, hàm này được yêu cầu phải nội tuyến để có thể sử dụng các tham số kiểu đã sửa đổi :
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
Sau đó, có thể được sử dụng theo một trong hai cách sau:
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
Và toàn bộ quá trình có thể được bao bọc thành một hàm mở rộng cho Gsonví dụ:
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
Vì vậy, bạn có thể chỉ cần gọi cho Gson và không phải lo lắng về TypeToken:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Ở đây Kotlin đang sử dụng kiểu suy luận từ một phía của nhiệm vụ hoặc mặt khác, và các tổng thể được sửa đổi cho một hàm nội tuyến để chuyển qua kiểu đầy đủ (không tẩy xóa) và sử dụng kiểu đó để tạo một TypeTokenvà cũng thực hiện lệnh gọi tới Gson
Gson().fromJson<kotlin.List<Turns>>(pref.turns)
Gson()hoặc chỉ Gsonnhư thể nó là tĩnh? Bạn cần cái đầu tiên, một ví dụ.
Một tùy chọn khác (không chắc nó trông thanh lịch hơn những cái khác) có thể là một cuộc gọi như thế này:
turns = Gson().fromJson(allPurchasesString, Array<Turns>::class.java).toMutableList()
Vì vậy, bạn đang sử dụng lớp java Array lớp một thay vì "Kotlin thuần túy".
Tôi đã sử dụng một cái gì đó như thế này để chuyển đổi Tsang string& Stringquay lại Tsử dụng Gson. Không chính xác những gì bạn đang tìm kiếm nhưng chỉ trong trường hợp.
Khai báo phần mở rộng
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)
Sử dụng
// 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
}
}
Điều này cũng hoạt động và đơn giản hơn
inline fun <reified T> Gson.fromJson(json: String) : T =
this.fromJson<T>(json, T::class.java)
Kotlin generic reified functioncủa Gson deserialize để ArrayList<T>sử dụng mã này
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