Saya mencoba memahami tujuan reifiedkata kunci, tampaknya itu memungkinkan kami untuk melakukan refleksi pada obat generik .
Namun, ketika saya tinggalkan itu berfungsi dengan baik. Adakah yang mau menjelaskan kapan ini membuat perbedaan nyata ?
Saya mencoba memahami tujuan reifiedkata kunci, tampaknya itu memungkinkan kami untuk melakukan refleksi pada obat generik .
Namun, ketika saya tinggalkan itu berfungsi dengan baik. Adakah yang mau menjelaskan kapan ini membuat perbedaan nyata ?
Jawaban:
reifiedbaik untukfun <T> myGenericFun(c: Class<T>)
Dalam tubuh fungsi generik seperti myGenericFun, Anda tidak dapat mengakses tipe Tkarena hanya tersedia pada waktu kompilasi tetapi terhapus saat runtime. Oleh karena itu, jika Anda ingin menggunakan tipe generik sebagai kelas normal di fungsi tubuh Anda harus secara eksplisit lulus kelas sebagai parameter seperti yang ditunjukkan pada myGenericFun.
Jika Anda membuat inlinefungsi dengan reified T , tipe Tdapat diakses bahkan saat runtime dan dengan demikian Anda tidak perlu meneruskannya Class<T>. Anda dapat bekerja dengan Tseolah-olah itu adalah kelas normal, misalnya Anda mungkin ingin memeriksa apakah suatu variabel adalah contoh dari T yang Anda dapat dengan mudah melakukan itu: myVar is T.
Seperti inlinefungsi dengan reifiedtipe Tpenampilan sebagai berikut:
inline fun <reified T> myGenericFun()
reifiedkerjanyaAnda hanya dapat menggunakan reifieddalam kombinasi dengan suatu inlinefungsi . Fungsi seperti itu membuat compiler menyalin bytecode fungsi ke setiap tempat di mana fungsi tersebut digunakan (fungsi tersebut sedang "digarisbawahi"). Ketika Anda memanggil fungsi inline dengan tipe reified, kompiler mengetahui tipe aktual yang digunakan sebagai argumen tipe dan memodifikasi bytecode yang dihasilkan untuk menggunakan kelas terkait secara langsung. Oleh karena itu panggilan seperti myVar is Tmenjadi myVar is String(jika argumen tipe String) di bytecode dan saat runtime.
Mari kita lihat contoh yang menunjukkan betapa bermanfaatnya reifiedhal itu. Kami ingin membuat fungsi ekstensi untuk Stringdipanggil toKotlinObjectyang mencoba untuk mengkonversi string JSON ke objek Kotlin biasa dengan tipe yang ditentukan oleh tipe generik fungsi T. Kita dapat menggunakan com.fasterxml.jackson.module.kotlinini dan pendekatan pertama adalah sebagai berikut:
a) Pendekatan pertama tanpa tipe reified
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
The readValueMetode mengambil jenis yang seharusnya untuk mengurai JsonObjectke. Jika kita mencoba untuk mendapatkan Classparameter tipe T, kompiler mengeluh: "Tidak dapat menggunakan 'T' sebagai parameter tipe reified. Gunakan kelas sebagai gantinya."
b) Penanganan masalah dengan Classparameter eksplisit
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
Sebagai solusinya, Classdari Tdapat dibuat parameter metode, yang kemudian digunakan sebagai argumen untuk readValue. Ini berfungsi dan merupakan pola umum dalam kode Java generik. Itu bisa disebut sebagai berikut:
data class MyJsonType(val name: String)
val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)
c) Cara Kotlin: reified
Menggunakan inlinefungsi dengan reifiedparameter tipe Tmemungkinkan untuk mengimplementasikan fungsi secara berbeda:
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
Tidak perlu untuk mengambil Classdari Ttambahan, Tdapat digunakan sebagai olah itu adalah kelas biasa. Untuk klien, kode ini terlihat seperti ini:
json.toKotlinObject<MyJsonType>()
Fungsi sebaris dengan reifiedtipe tidak dapat dipanggil dari kode Java .
SEDERHANA
* Reified adalah untuk memberikan izin untuk digunakan pada waktu kompilasi (untuk mengakses fungsi T inside de)
misalnya:
inline fun <reified T:Any> String.convertToObject(): T{
val gson = Gson()
return gson.fromJson(this,T::class.java)
}
menggunakan like:
val jsonStringResponse = "{"name":"bruno" , "age":"14" , "world":"mars"}"
val userObject = jsonStringResponse.convertToObject<User>()
println(user.name)