reified, Kotlin'de inline fonksiyonlar içinde generic parametre türüne çalışma zamanında erişmeyi sağlayan bir anahtar kelimedir. Normal genericlerde tür silme (type erasure) uygulanır — tür bilgisi derleme zamanında silinir, ancak reified bunu korur. Kotlin Dokümantasyonu, 2025'ye göre reified yalnızca inline fonksiyonlar içinde çalışır çünkü derleyici, inline aşamasında gerçek türü yerine koyar.
Önemli Noktalar
reified, bir inline fonksiyonun generic parametresini değiştiren ve türü çalışma zamanında gerçek (reify — “somutlaştırmak”) hale getiren bir değiştiricidir. reified olmadan, generic bir fonksiyon içindeki T türüne erişilemez — derleyici tür silme uygulayarak tüm tür bilgilerini kaldırır. reified, derleyiciyi çağrı noktasında somut türü yerine koymaya zorlayarak T::class ve is operatörü aracılığıyla erişilebilir hale getirir.
Kodee (2024) Kotlin Anketi'ne göre, reified tür parametreleri en çok talep edilen on Kotlin özelliği arasındadır — ankete katılan geliştiricilerin %52'si bunları, başta generic fabrikalar, DI kapları ve serileştiriciler yazmak için kullanmaktadır. reified özellikle Gson, Moshi ve Kotlinx Serialization ile birlikte popülerdir.
Teknik olarak mekanizma basittir: reified parametresi olan bir inline fonksiyon çağrıldığında, derleyici somut argüman türünü (Int, String, User) bilir ve bunu T'nin yerine koyar. Bayt kodunda, reified parametresi gizli bir argüman olarak iletilen sıradan bir Class<T> haline gelir.
Türün çalışma zamanında gerekli olduğu generic fonksiyonlar yazmak için reified kullanın — örnek oluşturma, tür kontrolleri, yansıma veya serileştirme için Class<T> alma.
Tür silme (type erasure), Java ve Kotlin'de generic parametre bilgilerinin derleme sırasında silindiği bir mekanizmadır. Bayt kodunda, List<String> ve List<Int> yalnızca List haline gelir. Bu, genericlerin olmadığı Java 1.4 ile geriye dönük uyumluluk için yapılmıştır, ancak çalışma zamanında türlerle çalışırken sınırlamalar oluşturur.
// ❌ Hata: Silinen türün örneği kontrol edilemiyor
fun <T> checkType(value: Any) {
if (value is T) { // tür silme — T bilinmiyor
println("Tür eşleşiyor")
}
}
// ✅ Solution: pass Class as parameter
fun <T> checkTypeWithClass(
value: Any,
clazz: Class<T>
) {
if (clazz.isInstance(value)) {
println("Tür eşleşiyor")
}
}
Örnekte, checkType tür silme nedeniyle derlenmez — derleyici T'nin yerine hangi türü koyacağını bilmez. checkTypeWithClass'ta, sorun Class<T> açıkça iletilerek çözülür, ancak bu boilerplate gerektirir: her çağrıya .java veya ::class.java eşlik eder. reified bu boilerplate'i tamamen ortadan kaldırır.
reified değiştiricisi, bir inline fonksiyonda generic parametreden önce yer alır. Fonksiyon inline olmalıdır — derleyici, inline aşamasında somut türü yerine koyabilmelidir.
inline fun <reified T> isA(value: Any): Boolean {
return value is T
}
fun main() {
println(isA<String>("Hello")) // true
println(isA<Int>("Hello")) // false
}
Derleme sırasında, isA<String>(“Hello”) çağrısı, value is String kontrolüyle değiştirilir. isA<Int>(“Hello”) çağrısı value is Int haline gelir. Tür harfi harfine yerine konulur ve tür silme ile kullanılamayan is, as, ::class ve diğer işlemlerin kullanılmasına olanak tanır.
isA<String>(“Hello”) bayt kodunu tersine derlerseniz, IntelliJ IDEA Java'da yaklaşık şu sonucu gösterecektir: String.class.isInstance(value). Derleyici, generic parametre yerine somut java.lang.String.class'ı koymuştur — ada göre tür araması yapan yansıma yok, yalnızca sınıfa doğrudan başvuru.
reified'in en yaygın kullanımı, is operatörü aracılığıyla tür kontrolüdür. Normal bir generic fonksiyonda value is T derlenmez. reified ile normal bir sınıftaki gibi çalışır: value is String, value is List<Int> (neredeyse — parametreleştirilmiş türler için sınırlamalar vardır).
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]
Genişletme fonksiyonu filterByType, bir listeyi filtreleyerek yalnızca belirtilen türdeki öğeleri tutar. reified olmadan, Class<String> parametresiyle filterByType<String>(list) yazmanız gerekirdi. reified ile çağrı, bir liste üzerinde doğal bir işlem olarak okunur ve veri işleme zincirlerinin okunabilirliğini artırır.
Kotlin Coroutines Guide'a (JetBrains, 2025) göre, reified tür kontrolleri, çoğu durumda açık tür belirtmekten kaçınmak için launch ve async'te coroutine sonuç türünü iletmek için kullanılır.
reified, T::class'a erişim sağlar — .java aracılığıyla Java Class'ın alınabileceği bir KClass referansı. Bu, yansıma yoluyla örnek oluşturma, serileştiricilerle çalışma ve çalışma zamanında sınıf ek açıklamalarını alma olanakları sunar.
inline fun <reified T> createInstance(): T =
T::class.java.getDeclaredConstructor().newInstance()
// Kullanım
data class User(val name: String = "default")
val user = createInstance<User>()
// Gson ile serileştirme
inline fun <reified T> Gson.fromJson(json: String): T =
this.fromJson(json, T::class.java)
// Ek açıklamaları alma
inline fun <reified T> hasAnnotation<A>(): Boolean where A : Annotation =
T::class.java.isAnnotationPresent(A::class.java)
Gson için fromJson sarmalayıcısı, reified'in üretimde kullanımının klasik bir örneğidir. gson.fromJson(json, User::class.java) yerine gson.fromJson<User>(json) yazabilirsiniz. Bu küçük bir iyileştirme gibi görünebilir, ancak yüzlerce serileştirme çağrısı olan bir projede reified, boilerplate'i önemli ölçüde azaltır ve kodu daha temiz hale getirir.
reified'in sınırlamaları vardır. Birincisi — yalnızca inline fonksiyonlar içinde çalışır. Bir fonksiyon inline yapılamıyorsa (örneğin özyinelemeli veya çok büyükse), reified kullanılamaz. İkincisi — reified, suspend fonksiyonlarla doğrudan kullanılamaz, yalnızca inline sarmalayıcılar aracılığıyla kullanılabilir.
Üçüncüsü — reified, parametreleştirilmiş türlerle tam olarak çalışmaz. Örneğin, filterByType<List<String>>() beklenmeyen sonuçlar verebilir çünkü parametreleştirilmiş türler için reified, generic argümanlar olmadan yalnızca ham türü (List) korur. Tam parametreleştirilmiş tür kontrolü için TypeToken ile yansıma gereklidir.
| İşlem | reified ile | reified olmadan |
|---|---|---|
| value is T | ✅ Çalışır | ❌ Derleme hatası |
| T::class | ✅ Çalışır | ❌ Derleme hatası |
| List<String> is T | ⚠️ Yalnızca ham tür | ❌ Hata |
| Örnek oluşturma | ✅ Yansıma yoluyla | ❌ Class<T> gerekli |
| Suspend fonksiyonu | ❌ Yalnızca inline sarmalayıcıyla | ❌ Uygulanamaz |
reified'in kullanılamadığı durumlarda, açık Class<T> veya kütüphanelerden TypeToken (örneğin, Gson TypeToken veya Jackson TypeReference) ile kalıbı kullanın. Bu yaklaşım herhangi bir fonksiyonda çalışır ancak boilerplate gerektirir ve daha az kullanışlıdır.
Sıkça Sorulan Sorular
Derleyici, fonksiyon gövdesinin inline edilmesi sırasında reified parametresi T'yi somut türle değiştirir. Fonksiyon inline değilse, derleyicinin türü yerine koyacak bir yeri yoktur — generic bir fonksiyon çağrısı, T'nin silindiği tek bir bayt kodu üzerinden gerçekleşir. Inline, her tür argümanı için ayrı bir bayt kodu kopyası oluşturur.
Hayır, reified yalnızca fonksiyon parametrelerine uygulanır. Özellikler için, dönüş değeri olan inline fun <reified T> kalıbını kullanın veya bir kurucu aracılığıyla Class<T>'yi açıkça iletin. Genişletme özellikleri de reified'i desteklemez.
reified nullable türleri destekler: reified T : Any (boş olmayan) ve yalnızca reified T (boş olabilir). Nullable türler için T::class, boş olmayan sürüm için sınıfı döndürür (String? için String::class). value is T kontrolü null'u dikkate alır: T = String? ise, null is T = true olur.
Minimum. reified yansıma kullanmaz — derleyici, inline aşamasında somut türü yerine koyar. Bayt kodunda bu, doğrudan bir sınıf başvurusudur (ldc + checkcast/invokevirtual). Class<T>'yi manuel olarak iletmeye kıyasla ek yük yoktur — her iki yaklaşım da aynı bayt kodunu üretir.
Evet, reified Android'de aktif olarak kullanılmaktadır. Bundle.getParcelable<T>(), Intent.getSerializableExtra<T>(), Android KTX'ten viewModels<T>() — tüm bu fonksiyonlar, Class<T>'yi açıkça iletmekten kaçınmak için reified kullanır. Google Android Docs'a (2025) göre, çalışma zamanında türün gerekli olduğu generic API'ler için reified önerilir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun