Soru Tarihi:
JVM'de çalışma zamanında jenerik parametreler hakkında bilgi bulunmamaktadır (type erasure). Kotlin, belirli bir tür T'nin çalışma zamanındaki bilgisine erişim sağlamak için inline fonksiyonlar için reified generic parametreler mekanizmasını önerdi, böylece Class<T> gibi işlemler yapmadan bu bilgilere erişilebiliyor. Bu, Kotlin dilinin en güçlü araçlarından biridir.
Problemi:
Bir T (jenerik) türünde bir değer alan bir fonksiyon yazmanız gerekiyor ve parametrenin türüne bağlı olarak farklı işlemler yapmalısınız, java.lang.Class'ı açıkça geçirmeden ve Java tarafında yansıma (reflection) kullanmadan. Geleneksel type erasure, çalışma zamanında T türünü öğrenmenizi sağlamaz.
Çözüm:
Kotlin'de inline fonksiyonlar için reified modifikasyonu ile generic parametrelerin tanımlanmasına izin verilir, bu da T türünü fonksiyonun gövdesinde "yoğurmanıza" olanak tanır, bu türle normal bir tür gibi çalışmanıza, tür kontrolü yapmanıza ve yansıma (reflection) aracılığıyla örnekler oluşturmanıza olanak tanır.
Kod örneği:
inline fun <reified T> isOfType(value: Any): Boolean { return value is T } isOfType<String>(123) // false isOfType<Int>(123) // true
Anahtar özellikler:
Reified'i inline fonksiyonlar dışında kullanmak mümkün mü?
Hayır! Sadece inline fonksiyonlar (ve inline tembel property’ler) reified generic parametreye sahip olabilir. Sebebi — çağrı noktasında kodun yerleştirilmesi, sadece bu şekilde T yerine belirli bir tür "yerleştirilebilir".
Kod örneği:
// Derleme hatası: fun <reified T> errorFun() { } // Doğru versiyon: inline fun <reified T> okFun() { }
Inline reified fonksiyonu içinde Class<T> elde etmek mümkün mü?
Evet! Bunun için T::class.java veya T::class yazmanız yeterlidir. Bu, generic fabrikalar, ayrıştırıcılar ve yansıma API'si ile çalışmak için oldukça kullanışlıdır.
Kod örneği:
inline fun <reified T> printType() { println(T::class.java) } printType<String>() // class java.lang.String
Reified fonksiyonu içinde T türünden nesneler oluşturmak mümkün mü?
Kısmen. Yansıma (reflection) kullanarak yapabilirsiniz, ancak C++ veya C#’taki gibi doğrudan new T() olarak yapamazsınız:
inline fun <reified T : Any> makeInstance(): T? { return T::class.constructors.firstOrNull()?.call() }
Ancak bu yaklaşım, T'nin parametresiz bir yapıcıya sahip olmasını gerektirir.
Reified ile yavaş bir yansıma (reflection) işlemi yürüten bir fonksiyon:
inline fun <reified T> foo(): T? = T::class.constructors.firstOrNull()?.call()
Artılar:
Eksiler:
Evrensel tür kontrolü veya safeCast için reified kullanımı:
inline fun <reified T> safeCast(value: Any?): T? = value as? T
Artılar:
Eksiler: