reified — kulcsszó a Kotlin nyelvben, amely lehetővé teszi a generic paraméter típusának elérését egy inline-függvényen belül futásidőben. A szokásos generics-nél type erasure működik — a típusra vonatkozó információ törlődik a fordítási fázisban, de a reified megőrzi azt. A Kotlin Documentation, 2025 szerint a reified csak inline-függvényeken belül működik, mivel a fordító behelyettesíti a valós típust a beágyazás fázisában.
Főbb pontok
reified — egy inline-függvény generic paraméterének módosítója, amely valóssá teszi a típust (reify — “megvalósít”) futásidőben. reified nélkül a T típus a generic függvényen belül nem érhető el — a fordító type erasure-t alkalmaz, törölve minden információt a típusról. reified arra kényszeríti a fordítót, hogy a konkrét típust a hívás helyén behelyettesítse, elérhetővé téve azt a T::class és az is operátor segítségével.
A Kotlin Survey by Kodee (2024) szerint a reified type parameters a tíz legkeresettebb Kotlin funkció közé tartozik — a megkérdezett fejlesztők 52%-a használja, főként generic gyárak, DI konténerek és szerializálók írásához. A reified különösen népszerű a Gson, Moshi és Kotlinx Serialization kombinációjával.
Technikailag a mechanizmus egyszerű: egy reified paraméterrel rendelkező inline-függvény meghívásakor a fordító ismeri az argumentum konkrét típusát (Int, String, User), és behelyettesíti a T helyére. A bájtkódban a reified-paraméter egy szokásos Class
Használja a reified-et olyan generic függvények írásához, ahol futásidőben szükség van a típusra — példányok létrehozása, típusellenőrzés, Class
Type erasure — a Java és Kotlin mechanizmusa, amelynél a generic paraméterekre vonatkozó információ törlődik a fordítás során. A bájtkódban a List
// ❌ Hiba: Nem ellenőrizhető a törölt típus példánya
fun <T> checkType(value: Any) {
if (value is T) { // type erasure — T ismeretlen
println("Típus egyezik")
}
}
// ✅ Solution: pass Class as parameter
fun <T> checkTypeWithClass(
value: Any,
clazz: Class<T>
) {
if (clazz.isInstance(value)) {
println("Típus egyezik")
}
}
A példában a checkType nem fordul le a type erasure miatt — a fordító nem tudja, milyen típust helyettesítsen a T helyére. A checkTypeWithClass esetében a probléma a Class
A reified módosító a generic paraméter előtt áll egy inline-függvényben. A függvénynek kötelezően inline-nak kell lennie — a fordítónak rendelkeznie kell a konkrét típus behelyettesítésének lehetőségével a beágyazás fázisában.
inline fun <reified T> isA(value: Any): Boolean {
return value is T
}
fun main() {
println(isA<String>("Helló")) // true
println(isA<Int>("Helló")) // false
}
A fordítás során az isA
Ha dekompiláljuk az isA
A reified leggyakoribb alkalmazása — típusellenőrzés az is operátoron keresztül. Egy szokásos generic függvényben a value is T nem fordul le. A reified-del ez úgy működik, mint egy szokásos osztály esetében: 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]
A filterByType kiterjesztő függvény szűri a listát, csak a megadott típus elemeit hagyva meg. reified nélkül a filterByType
Az adatok szerint Kotlin Coroutines Guide (JetBrains, 2025), a reified típusellenőrzéseket a launch és async függvényekben használják a korutin eredménytípusának átadására, ami lehetővé teszi a típus explicit megadásának elkerülését a legtöbb esetben.
A reified hozzáférést biztosít a T::class-hoz — egy KClass-ra való hivatkozáshoz, amelyből a .java segítségével Java Class nyerhető. Ez lehetőségeket nyit a példányok reflexió általi létrehozására, a szerializálókkal való munkára és az osztályannotációk futásidőben történő lekérésére.
inline fun <reified T> createInstance(): T =
T::class.java.getDeclaredConstructor().newInstance()
// Használat
data class User(val name: String = "default")
val user = createInstance<User>()
// Szerializáció Gson-nal
inline fun <reified T> Gson.fromJson(json: String): T =
this.fromJson(json, T::class.java)
// Annotációk lekérése
inline fun <reified T> hasAnnotation<A>(): Boolean where A : Annotation =
T::class.java.isAnnotationPresent(A::class.java)
A fromJson wrapper a Gson számára — klasszikus példa a reified használatára éles környezetben. A gson.fromJson(json, User::class.java) helyett írható gson.fromJson
A reified-nek vannak korlátai. Első — csak inline-függvényeken belül működik. Ha a függvény nem tehető inline-ná (például rekurzív vagy túl nagy), a reified nem érhető el. Második — a reified nem használható közvetlenül suspend-függvényekkel, csak inline wrappereken keresztül.
Harmadik — a reified nem működik teljes mértékben a paraméterezett típusokkal. Például a filterByType>() váratlan eredményt adhat, mivel a paraméterezett típusok esetén a reified csak a nyers típust (List) őrzi meg, a generic argumentumok megadása nélkül. A paraméterezett típusok teljes ellenőrzéséhez TypeToken-nel történő reflexió szükséges.
| Művelet | Reified-del | Reified nélkül |
|---|---|---|
| value is T | ✅ Működik | ❌ Fordítási hiba |
| T::class | ✅ Működik | ❌ Fordítási hiba |
| List | ⚠️ Csak raw type | ❌ Hiba |
| Példány létrehozása | ✅ Reflexióval | ❌ Class |
| Suspend függvény | ❌ Csak inline wrapperen keresztül | ❌ Nem alkalmazható |
Azokban az esetekben, amikor a reified nem érhető el, használja a Class
Gyakran ismételt kérdések
A fordító a reified T paramétert a konkrét típussal helyettesíti a függvény törzsének beágyazása során. Ha a függvény nem inline, a fordítónak nincs helye a típus behelyettesítésére — a generic függvény hívása egységes bájtkódon keresztül történik, ahol a T törlődött. Inline külön bájtkód-másolatot hoz létre minden típus-argumentumhoz.
Nem, a reified csak függvényparaméterekre alkalmazható. Tulajdonságok esetén az inline fun
A reified támogatja a nullable típusokat: reified T : Any (non-null) és egyszerűen reified T (lehet nullable). A nullable típusok esetén a T::class a non-null verzióhoz tartozó osztályt adja vissza (String::class a String? esetén). A value is T ellenőrzés figyelembe veszi a null-t: ha T = String?, akkor null is T = true.
Minimális. A reified nem használ reflexiót — a fordító a konkrét típust a beágyazás fázisában helyettesíti be. A bájtkódban ez közvetlen hivatkozás az osztályra (ldc + checkcast/invokevirtual). Nincs overhead a Class
Igen, a reified aktívan használatos Androidban. Bundle.getParcelable
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is