Kotlin میں Reified — یہ کیا ہے، نحو اور استعمال

مصنف: IT Sectr اشاعت: 2026-06-21 مطالعے کا وقت: 8 منٹ

reified — Kotlin زبان میں ایک کلیدی لفظ ہے جو inline-فنکشن کے اندر generic-پیرامیٹر کی قسم تک runtime میں رسائی کی اجازت دیتا ہے۔ عام generics میں type erasure کام کرتا ہے — قسم کی معلومات کمپائلیشن کے مرحلے پر مٹ جاتی ہیں، لیکن reified اسے محفوظ رکھتا ہے۔ Kotlin Documentation, 2025 کے مطابق، reified صرف inline-فنکشنز کے اندر کام کرتا ہے، کیونکہ کمپائلر اصلی قسم کو inlining کے مرحلے پر داخل کرتا ہے۔

اہم نکات

  • reified — generic-پیرامیٹر کا موڈیفائر جو runtime میں قسم کی معلومات محفوظ رکھتا ہے
  • Inline only — reified صرف inline-فنکشنز کے اندر کام کرتا ہے
  • Type erasure — Java/Kotlin کا معیاری طریقہ کار جو generic-اقسام کو مٹاتا ہے؛ reified اسے نظرانداز کرتا ہے
  • is کی جانچ — ممکن: if (value is T) بجائے if (value is String)
  • مثالیں بنانا — T::class.java.newInstance() بغیر Class منتقل کیے

Kotlin میں reified کیا ہے؟

reified — inline-فنکشن کے generic-پیرامیٹر کا ایک موڈیفائر ہے جو runtime میں قسم کو حقیقی (reify — «حقیقی بنانا») بناتا ہے۔ reified کے بغیر generic-فنکشن کے اندر T کی قسم قابل رسائی نہیں ہے — کمپائلر type erasure کا اطلاق کرتا ہے، قسم کے بارے میں تمام معلومات مٹا دیتا ہے۔ reified کمپائلر کو مجبور کرتا ہے کہ وہ کال کی جگہ پر مخصوص قسم داخل کرے، اسے T::class اور is آپریٹر کے ذریعے قابل رسائی بنائے۔

Kotlin Survey by Kodee (2024) کے مطابق، reified type parameters Kotlin کی دس سب سے زیادہ مطلوبہ خصوصیات میں شامل ہیں — انہیں 52% جواب دہندگان استعمال کرتے ہیں، خاص طور پر generic-فیکٹریز، DI-کنٹینرز اور سیریلائزرز لکھنے کے لیے۔ reified خاص طور پر Gson، Moshi اور Kotlinx Serialization کے ساتھ مقبول ہے۔

تکنیکی طور پر طریقہ کار آسان ہے: reified پیرامیٹر کے ساتھ inline-فنکشن کو کال کرتے وقت، کمپائلر آرگیومنٹ کی مخصوص قسم (Int, String, User) جانتا ہے اور اسے T کی جگہ داخل کرتا ہے۔ بائٹ کوڈ میں reified-پیرامیٹر ایک عام Class میں تبدیل ہو جاتا ہے، جو ایک پوشیدہ آرگیومنٹ کے طور پر منتقل ہوتا ہے۔

reified کو generic-فنکشنز لکھنے کے لیے استعمال کریں جہاں runtime میں قسم کی ضرورت ہو — مثالیں بنانا، قسم کی جانچ، ریفلیکشن یا سیریلائزیشن کے لیے Class حاصل کرنا۔

generics میں type erasure کا مسئلہ

Type erasure — Java اور Kotlin کا وہ طریقہ کار ہے جس میں generic-پیرامیٹرز کی معلومات کمپائلیشن کے دوران مٹ جاتی ہیں۔ بائٹ کوڈ میں List اور List صرف List بن جاتے ہیں۔ یہ Java 1.4 کے ساتھ پسماندہ مطابقت کے لیے کیا گیا تھا، جہاں generics موجود نہیں تھے، لیکن runtime میں اقسام کے ساتھ کام کرتے وقت حدود پیدا کرتا ہے۔

kotlin
// ❌ خرابی: مٹائی گئی قسم کی مثال کی جانچ نہیں کر سکتے
fun <T> checkType(value: Any) {
    if (value is T) { // type erasure — T نامعلوم ہے
        println("قسم مماثل ہے")
    }
}

// ✅ Solution: pass Class as parameter
fun <T> checkTypeWithClass(
    value: Any,
    clazz: Class<T>
) {
    if (clazz.isInstance(value)) {
        println("قسم مماثل ہے")
    }
}

مثال میں checkType type erasure کی وجہ سے کمپائل نہیں ہوتا — کمپائلر نہیں جانتا کہ T کی جگہ کون سی قسم ڈالنی ہے۔ checkTypeWithClass میں مسئلہ Class کو واضح طور پر منتقل کرکے حل کیا گیا ہے، لیکن اس کے لیے boilerplate درکار ہے: ہر کال کے ساتھ .java یا ::class.java ہوتا ہے۔ reified اس boilerplate کو مکمل طور پر ختم کرتا ہے۔

reified کا نحو اور کام کرنے کا طریقہ کار

reified موڈیفائر inline-فنکشن میں generic-پیرامیٹر سے پہلے لگایا جاتا ہے۔ فنکشن لازماً inline ہونا چاہیے — کمپائلر کے پاس inlining کے مرحلے پر مخصوص قسم داخل کرنے کی صلاحیت ہونی چاہیے۔

kotlin
inline fun <reified T> isA(value: Any): Boolean {
    return value is T
}

fun main() {
    println(isA<String>("ہیلو")) // true
    println(isA<Int>("ہیلو"))  // false
}

کمپائلیشن کے دوران isA("Hello") کی کال value is String کی جانچ میں تبدیل ہو جاتی ہے۔ isA("Hello") کی کال value is Int میں تبدیل ہو جاتی ہے۔ قسم لفظی طور پر داخل کی جاتی ہے، جس سے is, as, ::class اور دیگر آپریشنز استعمال کرنا ممکن ہو جاتا ہے جو type erasure کے وقت دستیاب نہیں ہوتے۔

reified-فنکشن کا ڈی کمپائلیشن

اگر isA("Hello") کے بائٹ کوڈ کو ڈی کمپائل کیا جائے تو IntelliJ IDEA Java میں تقریباً یہ نتیجہ دکھائے گا: String.class.isInstance(value)۔ کمپائلر نے generic-پیرامیٹر کی جگہ مخصوص java.lang.String.class داخل کر دیا — نام سے قسم تلاش کرنے والی کوئی ریفلیکشن نہیں، صرف براہ راست کلاس ریفرنس۔

reified کے ساتھ قسم کی جانچ: is اور as

reified کا سب سے عام استعمال is آپریٹر کے ذریعے قسم کی جانچ ہے۔ عام generic-فنکشن میں value is T کمپائل نہیں ہوتا۔ reified کے ساتھ یہ عام کلاس کی طرح کام کرتا ہے: value is String, value is List (تقریباً — parameterized اقسام کے لیے reified کی حدود کو مدنظر رکھتے ہوئے)۔

kotlin
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]

Extension function filterByType صرف مخصوص قسم کے عناصر کو رکھتے ہوئے فہرست کو فلٹر کرتا ہے۔ reified کے بغیر filterByType(list) کو Class پیرامیٹر کے ساتھ لکھنا پڑتا۔ reified کے ساتھ کال فہرست پر قدرتی آپریشن کی طرح پڑھی جاتی ہے، جو ڈیٹا پروسیسنگ چینز کی پڑھنے کی اہلیت کو بہتر بناتا ہے۔

Kotlin Coroutines Guide (JetBrains, 2025) کے مطابق، reified type checks launch اور async میں کوروٹین کے نتیجے کی قسم منتقل کرنے کے لیے استعمال ہوتے ہیں، جو زیادہ تر معاملات میں قسم کو واضح طور پر بتانے کی ضرورت سے بچاتا ہے۔

reified کے ساتھ ریفلیکشن: مثالیں بنانا اور Class تک رسائی

reified T::class تک رسائی دیتا ہے — KClass کا حوالہ، جس سے .java کے ذریعے Java Class حاصل کیا جا سکتا ہے۔ یہ ریفلیکشن کے ذریعے مثالیں بنانے، سیریلائزرز کے ساتھ کام کرنے اور runtime میں کلاس کی تشریحات حاصل کرنے کے امکانات کھولتا ہے۔

kotlin
inline fun <reified T> createInstance(): T =
    T::class.java.getDeclaredConstructor().newInstance()

// استعمال
data class User(val name: String = "default")
val user = createInstance<User>()

// Gson کے ساتھ سیریلائزیشن
inline fun <reified T> Gson.fromJson(json: String): T =
    this.fromJson(json, T::class.java)

// تشریحات حاصل کرنا
inline fun <reified T> hasAnnotation<A>(): Boolean where A : Annotation =
    T::class.java.isAnnotationPresent(A::class.java)

Gson کے لیے fromJson ریپر — production میں reified استعمال کرنے کی کلاسک مثال۔ gson.fromJson(json, User::class.java) کی بجائے gson.fromJson(json) لکھا جا سکتا ہے۔ یہ ایک چھوٹی بہتری لگتی ہے، لیکن سینکڑوں سیریلائزیشن کالز والے پروجیکٹ میں reified boilerplate کو نمایاں طور پر کم کرتا ہے اور کوڈ کو صاف ستھرا بناتا ہے۔

reified کی حدود اور متبادل

reified کی حدود ہیں۔ پہلی — یہ صرف inline-فنکشنز کے اندر کام کرتا ہے۔ اگر فنکشن کو inline نہیں بنایا جا سکتا (مثلاً یہ recursive ہے یا بہت بڑی ہے)، تو reified دستیاب نہیں ہے۔ دوسری — reified کو suspend-فنکشنز کے ساتھ براہ راست استعمال نہیں کیا جا سکتا، صرف inline-ریپرز کے ذریعے۔

تیسری — reified parameterized اقسام کے ساتھ مکمل طور پر کام نہیں کرتا۔ مثال کے طور پر، filterByType>() غیر متوقع نتیجہ دے سکتا ہے، کیونکہ parameterized اقسام کے لیے reified صرف خام قسم (List) کو محفوظ رکھتا ہے، generic-آرگیومنٹس کے بغیر۔ parameterized اقسام کی مکمل جانچ کے لیے TypeToken کے ساتھ ریفلیکشن درکار ہے۔

عملreified کے ساتھreified کے بغیر
value is T✅ کام کرتا ہے❌ کمپائلیشن کی خرابی
T::class✅ کام کرتا ہے❌ کمپائلیشن کی خرابی
List is T⚠️ صرف raw type❌ خرابی
مثال بنانا✅ ریفلیکشن کے ذریعے❌ Class درکار ہے
Suspend-فنکشن❌ صرف inline ریپر کے ذریعے❌ قابل اطلاق نہیں

جب reified دستیاب نہ ہو، تو لائبریریوں سے Class یا TypeToken (مثلاً Gson TypeToken یا Jackson TypeReference) واضح طور پر منتقل کرنے کا پیٹرن استعمال کریں۔ یہ طریقہ کسی بھی فنکشن میں کام کرتا ہے، لیکن اس کے لیے boilerplate درکار ہے اور یہ کم آسان ہے۔

اکثر پوچھے گئے سوالات

reified صرف inline-فنکشنز کے ساتھ کیوں کام کرتا ہے؟

کمپائلر reified-پیرامیٹر T کو فنکشن کے باڈی کو inlining کرتے وقت مخصوص قسم سے بدل دیتا ہے۔ اگر فنکشن inline نہیں ہے، تو کمپائلر کے پاس قسم ڈالنے کی جگہ نہیں ہوتی — generic-فنکشن کی کال ایک یونیفائیڈ بائٹ کوڈ کے ذریعے ہوتی ہے جہاں T مٹا دیا جاتا ہے۔ Inline ہر قسم-آرگیومنٹ کے لیے بائٹ کوڈ کی علیحدہ کاپی بناتا ہے۔

کیا reified property کا اعلان کیا جا سکتا ہے؟

نہیں، reified صرف فنکشن کے پیرامیٹرز پر لاگو ہوتا ہے۔ پراپرٹیز کے لیے inline fun پیٹرن استعمال کیا جاتا ہے جس میں ویلیو واپس کی جاتی ہے، یا کنسٹرکٹر کے ذریعے Class واضح طور پر منتقل کیا جاتا ہے۔ Extension properties بھی reified کو سپورٹ نہیں کرتیں۔

reified nullable-اقسام کے ساتھ کیسے کام کرتا ہے؟

reified nullable-اقسام کو سپورٹ کرتا ہے: reified T : Any (non-null) اور صرف reified T (nullable ہو سکتا ہے)۔ nullable-اقسام کے لیے T::class non-null ورژن کے لیے کلاس لوٹاتا ہے (String? کے لیے String::class)۔ value is T کی جانچ null کو مدنظر رکھتی ہے: اگر T = String? ہے تو null is T = true۔

کیا reified کا کوئی اوورہیڈ ہے؟

کم سے کم۔ reified ریفلیکشن استعمال نہیں کرتا — کمپائلر inlining کے مرحلے پر مخصوص قسم داخل کرتا ہے۔ بائٹ کوڈ میں یہ کلاس کا براہ راست حوالہ ہوتا ہے (ldc + checkcast/invokevirtual)۔ Class کے دستی منتقلی کے مقابلے میں کوئی اوورہیڈ نہیں — دونوں طریقے ایک جیسا بائٹ کوڈ بناتے ہیں۔

کیا Android ڈیولپمنٹ میں reified استعمال کیا جا سکتا ہے؟

ہاں، reified Android میں بڑے پیمانے پر استعمال ہوتا ہے۔ Bundle.getParcelable(), Intent.getSerializableExtra(), viewModels() Android KTX سے — یہ تمام فنکشنز reified استعمال کرتے ہیں تاکہ Class کو واضح طور پر منتقل کرنے سے بچا جا سکے۔ Google Android Docs (2025) کے مطابق، reified کو generic-API کے لیے تجویز کیا جاتا ہے جہاں runtime میں قسم کی ضرورت ہو۔

خلاصہ

  • reified — inline-فنکشن کے generic-پیرامیٹر کا موڈیفائر جو runtime میں قسم کو محفوظ رکھتا ہے
  • Type erasure — اقسام کو مٹانے کا معیاری طریقہ کار؛ reified inlining کے ذریعے اسے نظرانداز کرتا ہے
  • is/as — قسم کی جانچ اور تبدیلی reified کے ساتھ عام کلاسز کی طرح کام کرتی ہے
  • کلاس-حوالہ — T::class اور T::class.java ریفلیکشن اور سیریلائزیشن کے لیے دستیاب ہیں
  • صرف Inline — reified inline-فنکشن کے بغیر قسم داخل کرنے کے طریقہ کار کی وجہ سے ممکن نہیں
  • Parameterized اقسام — reified generic-آرگیومنٹس کو محفوظ نہیں رکھتا (صرف raw type)
  • استعمال — Gson/Moshi سیریلائزیشن، DI-کنٹینرز، کلیکشنز میں قسم کی جانچ، Android KTX

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں