reified — kata kunci dalam bahasa Kotlin yang memungkinkan akses ke tipe parameter generic di dalam inline-function pada saat eksekusi. Dalam generic biasa, type erasure bekerja — informasi tentang tipe dihapus pada tahap kompilasi, tetapi reified menyimpannya. Menurut Kotlin Documentation, 2025, reified hanya bekerja di dalam inline-function, karena kompiler mensubstitusi tipe nyata pada tahap inlining.
Poin utama
reified — adalah pengubah parameter generic dari fungsi inline yang membuat tipe menjadi nyata (reify — “menjadikan nyata”) di runtime. Tanpa reified, tipe T di dalam fungsi generic tidak dapat diakses — kompiler menerapkan type erasure, menghapus semua informasi tentang tipe. reified memaksa kompiler untuk mensubstitusi tipe konkret di tempat pemanggilan, membuatnya dapat diakses melalui T::class dan operator is.
Menurut Kotlin Survey by Kodee (2024), reified type parameters termasuk dalam sepuluh fitur Kotlin yang paling banyak diminati — 52% pengembang yang disurvei menggunakannya, terutama untuk menulis pabrik generic, container DI, dan serializer. Reified sangat populer dalam kombinasi dengan Gson, Moshi, dan Kotlinx Serialization.
Secara teknis, mekanismenya sederhana: saat memanggil fungsi inline dengan parameter reified, kompiler mengetahui tipe konkret argumen (Int, String, User) dan mensubstitusikannya ke tempat T. Dalam bytecode, parameter reified berubah menjadi Class
Gunakan reified untuk menulis fungsi generic di mana tipe diperlukan di runtime — pembuatan instance, pemeriksaan tipe, mendapatkan Class
Type erasure — mekanisme Java dan Kotlin di mana informasi tentang parameter generic dihapus selama kompilasi. Dalam bytecode, List
// ❌ Galat: Tidak dapat memeriksa instance dari tipe yang dihapus
fun <T> checkType(value: Any) {
if (value is T) { // type erasure — T tidak diketahui
println("Tipe cocok")
}
}
// ✅ Solution: pass Class as parameter
fun <T> checkTypeWithClass(
value: Any,
clazz: Class<T>
) {
if (clazz.isInstance(value)) {
println("Tipe cocok")
}
}
Dalam contoh, checkType tidak dapat dikompilasi karena type erasure — kompiler tidak tahu tipe apa yang harus disubstitusi ke tempat T. Di checkTypeWithClass masalah diselesaikan dengan mengirimkan Class
Pengubah reified ditempatkan sebelum parameter generic dalam fungsi inline. Fungsi harus inline — kompiler harus memiliki kemampuan untuk mensubstitusi tipe konkret pada tahap inlining.
inline fun <reified T> isA(value: Any): Boolean {
return value is T
}
fun main() {
println(isA<String>("Halo")) // true
println(isA<Int>("Halo")) // false
}
Selama kompilasi, pemanggilan isA
Jika kita mendekompilasi bytecode isA
Penerapan reified yang paling umum — pemeriksaan tipe melalui operator is. Dalam fungsi generic biasa, value is T tidak dapat dikompilasi. Dengan reified, ini bekerja seperti dengan kelas biasa: value is String, value is List
inline fun <reified T> List<Any>.filterByType(): List<T> {
return this.filter { it is T }.map { it as T }
}
val mixed = listOf("a", 1, "b", 2)
val strings = mixed.filterByType<String>() // ["a", "b"]
val ints = mixed.filterByType<Int>() // [1, 2]
Fungsi ekstensi filterByType memfilter daftar, hanya menyisakan elemen dari tipe yang ditentukan. Tanpa reified, harus menulis filterByType
Menurut data Kotlin Coroutines Guide (JetBrains, 2025), pemeriksaan tipe reified digunakan di launch dan async untuk mengirimkan tipe hasil coroutine, yang memungkinkan menghindari penentuan tipe secara eksplisit di sebagian besar kasus.
reified memberikan akses ke T::class — referensi ke KClass, dari mana Java Class dapat diperoleh melalui .java. Ini membuka kemungkinan untuk pembuatan instance melalui refleksi, bekerja dengan serializer, dan mendapatkan anotasi kelas selama eksekusi.
inline fun <reified T> createInstance(): T =
T::class.java.getDeclaredConstructor().newInstance()
// Penggunaan
data class User(val name: String = "default")
val user = createInstance<User>()
// Serialisasi dengan Gson
inline fun <reified T> Gson.fromJson(json: String): T =
this.fromJson(json, T::class.java)
// Mendapatkan anotasi
inline fun <reified T> hasAnnotation<A>(): Boolean where A : Annotation =
T::class.java.isAnnotationPresent(A::class.java)
Wrapper fromJson untuk Gson — contoh klasik penggunaan reified di produksi. Alih-alih gson.fromJson(json, User::class.java) dapat menulis gson.fromJson
reified memiliki keterbatasan. Pertama — hanya bekerja di dalam fungsi inline. Jika fungsi tidak dapat dibuat inline (misalnya rekursif atau terlalu besar), reified tidak tersedia. Kedua — reified tidak dapat digunakan langsung dengan fungsi suspend, hanya melalui wrapper inline.
Ketiga — reified tidak bekerja sepenuhnya dengan tipe yang diparametrisasi. Misalnya, filterByType>() dapat memberikan hasil yang tidak terduga, karena untuk tipe yang diparametrisasi, reified hanya menyimpan tipe mentah (List), tanpa menentukan argumen generic. Untuk pemeriksaan lengkap tipe yang diparametrisasi, diperlukan refleksi dengan TypeToken.
| Operasi | Dengan reified | Tanpa reified |
|---|---|---|
| value is T | ✅ Berfungsi | ❌ Galat kompilasi |
| T::class | ✅ Berfungsi | ❌ Galat kompilasi |
| List | ⚠️ Hanya raw type | ❌ Galat |
| Pembuatan instance | ✅ Melalui refleksi | ❌ Perlu Class |
| Fungsi Suspend | ❌ Hanya melalui wrapper inline | ❌ Tidak berlaku |
Untuk kasus di mana reified tidak tersedia, gunakan pola dengan pengiriman eksplisit Class
Pertanyaan yang sering diajukan
Kompiler mengganti parameter reified T dengan tipe konkret selama inlining body fungsi. Jika fungsi tidak inline, kompiler tidak memiliki tempat untuk mensubstitusi tipe — pemanggilan fungsi generic terjadi melalui bytecode seragam, di mana T telah dihapus. Inline membuat salinan bytecode terpisah untuk setiap tipe-argumen.
Tidak, reified hanya berlaku untuk parameter fungsi. Untuk properti, gunakan pola inline fun
reified mendukung tipe nullable: reified T : Any (non-null) dan sederhana reified T (dapat nullable). Untuk tipe nullable, T::class mengembalikan kelas untuk versi non-null (String::class untuk String?). Pemeriksaan value is T memperhitungkan null: jika T = String?, maka null is T = true.
Minimal. reified tidak menggunakan refleksi — kompiler mensubstitusi tipe konkret pada tahap inlining. Dalam bytecode, ini adalah referensi langsung ke kelas (ldc + checkcast/invokevirtual). Tidak ada overhead dibandingkan dengan pengiriman manual Class
Ya, reified digunakan secara aktif di Android. Bundle.getParcelable
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga