ایپ ڈیولپمنٹ میں Reflection — یہ کیا ہے، ریفلیکشن کے طریقہ کار اور انہیں کیسے استعمال کریں

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

Reflection (ریفلیکشن) ایک رن ٹائم میکانزم ہے جو کوڈ کو اپنی ساخت کا جائزہ لینے کی اجازت دیتا ہے: کمپائل کے وقت اقسام جانے بغیر کلاسز، میتھڈز، فیلڈز اور اینوٹیشنز حاصل کرنا۔ یہ ٹول بہت سے موبائل فریم ورکس کی بنیاد ہے — JSON سیریلائزیشن (Gson, Moshi)، ڈیپنڈنسی انجیکشن (Dagger, Koin) اور ٹیسٹ رنرز (JUnit, XCTest)۔ Oracle Java Reflection Tutorial, 2024 کے مطابق، reflection Java پلیٹ فارم کا لازمی عنصر ہے، جسے تمام بڑی لائبریریاں استعمال کرتی ہیں۔

اہم نکات

  • Reflection پروگرام کے چلنے کے دوران کلاسز، میتھڈز اور فیلڈز کے میٹا ڈیٹا تک رسائی ہے۔
  • Java Reflection API متحرک تجزیہ کے لیے Class، Method، Field اور Constructor کلاسز فراہم کرتا ہے۔
  • Kotlin ریفلیکشن KClass اور KFunction استعمال کرتا ہے، جو کوروٹینز اور سیریلائزیشن کے ساتھ مربوط ہیں۔
  • Objective-C Runtime class_copyMethodList اور objc_getClass کے ذریعے reflection کی ایک شکل ہے۔
  • reflection کی کارکردگی JIT اصلاحات کی کمی کی وجہ سے براہ راست کالز سے 10–100 گنا کم ہے۔

Reflection کیا ہے؟

Reflection کسی پروگرام کی اپنی ساخت اور رویے کا مشاہدہ اور ترمیم کرنے کی صلاحیت ہے جو عمل کے دوران ہوتی ہے۔ آبجیکٹ پر مبنی زبانوں میں اس کا مطلب Class، Method، Field اور Constructor آبجیکٹس حاصل کرنا ہے، جو پروگرام کے عناصر کو پڑھنے اور کال کرنے کے لیے دستیاب ڈیٹا کے طور پر ظاہر کرتے ہیں۔

“reflection” اصطلاح 1982 میں مصنوعی ذہانت کی کمیونٹی (Brian Cantwell Smith) میں متعارف کرائی گئی اور Smalltalk زبان میں نافذ کی گئی۔ موبائل ڈیولپمنٹ میں، reflection پہلی بار Java ME اور Objective-C (1986, NextStep) میں ظاہر ہوا۔ آج ہر بڑے موبائل پلیٹ فارم کا اپنا reflection API ہے: Android کے لیے Java/Kotlin، iOS کے لیے Objective-C Runtime، Swift کے لیے Swift Mirror API۔

reflection کا میکانزم میٹا ڈیٹا پر مبنی ہے جسے کمپائلر بائٹ کوڈ یا بائنری میں محفوظ کرتا ہے۔ Android DEX فائلوں میں کلاسز کے بارے میں مکمل معلومات ذخیرہ کرتا ہے، iOS Mach-O سیگمنٹ کے __objc_classlist سیکشن میں۔ رن ٹائم ان میٹا ڈیٹا کو میموری میں لوڈ کرتا ہے اور انہیں عبور کرنے کے لیے API فراہم کرتا ہے۔

Java اور Kotlin میں Reflection کیسے کام کرتا ہے

Java Reflection API java.lang.Class کلاس کے گرد تعمیر کیا گیا ہے۔ Java میں کسی بھی آبجیکٹ کو .getClass() یا Class.forName() کے ذریعے Class میں تبدیل کیا جا سکتا ہے۔ Class سے تمام میتھڈز، فیلڈز، کنسٹرکٹرز، اینوٹیشنز اور سپر کلاسز نکالی جاتی ہیں۔ Kotlin Java ریفلیکشن کو وراثت میں لیتا ہے اور kotlin.reflect پیکیج سے اپنی KClass، KFunction، KProperty کا اضافہ کرتا ہے۔

kotlin
import kotlin.reflect.full.declaredMemberFunctions

data class User(
    val name: String,
    val email: String
)

fun inspectClass() {
    val kClass = User::class
    val properties = kClass.declaredMemberProperties
    val functions = kClass.declaredMemberFunctions

    properties.forEach { prop ->
        println("خصوصیت: ${prop.name}، قسم: ${prop.returnType}")
    }
}

اس مثال میں KClass data class User کے لیے میٹا ڈیٹا فراہم کرتا ہے۔ declaredMemberProperties ان کی اقسام اور گیٹرز کے ساتھ خصوصیات کی فہرست لوٹاتا ہے۔ Kotlin ریفلیکشن کوروٹینز کے ساتھ قریب سے مربوط ہے: KFunction suspend ماڈیفائر کو سپورٹ کرتا ہے، جو reflection کے ذریعے غیر متزامن میتھڈز کو کال کرنے کی اجازت دیتا ہے۔

Java Reflection: Class, Method, Field

Java reflection Class<?>، Method.setAccessible() اور Field.get() کے ساتھ کام کرتا ہے۔ setAccessible(true) پرائیویٹ عناصر کے لیے Java زبان کے رسائی کنٹرول کی جانچ کو غیر فعال کرتا ہے۔ یہ طاقتور لیکن خطرناک میکانزم ہے: Android پر API 28 سے شروع کرکے، پوشیدہ سسٹم میتھڈز پر setAccessible کال کرنے سے InaccessibleObjectException ہو سکتی ہے۔

java
// Java reflection: پرائیویٹ میتھڈ کی کال
Class clazz = Class.forName("com.example.MyClass");
Object instance = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getDeclaredMethod("privateMethod", String.class);
method.setAccessible(true);
method.invoke(instance, "reflection test");

کوڈ Class.forName() کو ظاہر کرتا ہے — سٹرنگ نام کے ذریعے متحرک کلاس لوڈنگ۔ یہ پلگ ان آرکیٹیکچر کی بنیاد ہے: ایک کلاس کمپائل کے وقت نامعلوم ہو سکتی ہے، لیکن رن ٹائم میں reflection کے ذریعے لوڈ اور عمل میں لائی جا سکتی ہے۔ getDeclaredMethod(“privateMethod”, ...) ایک میتھڈ کو نام اور پیرامیٹر اقسام سے ڈھونڈتا ہے، اور invoke اسے انجام دیتا ہے۔

Objective-C Runtime: ریفلیکشن کا متبادل ماڈل

Objective-C رن ٹائم class_copyMethodList، class_copyPropertyList، objc_getAssociatedObject فنکشنز فراہم کرتا ہے۔ Java کے برعکس، Objective-C پرائیویٹ میتھڈز کو پہلے سے نہیں چھپاتا — رن ٹائم کلاس کے تمام میتھڈز دیکھتا ہے۔ یہ وضاحت کرتا ہے کہ method swizzling setAccessible کے بغیر کیوں کام کرتا ہے: رن ٹائم میں میٹا ڈیٹا کی سطح پر encapsulation نہیں ہے۔

موبائل ڈیولپمنٹ میں Reflection کا استعمال

Reflection موبائل ڈیولپمنٹ کی اہم لائبریریوں میں استعمال ہوتا ہے۔ JSON سیریلائزیشن (Gson, Moshi, Kotlinx.serialization) reflection کے ذریعے آبجیکٹ کی خصوصیات حاصل کرتا ہے اور انہیں JSON کلیدوں سے ملتا ہے۔ ڈیپنڈنسی انجیکشن (Dagger, Koin, Swinject) خودکار ڈیپنڈنسی انجیکشن کے لیے کنسٹرکٹرز اور فیلڈز کا تجزیہ کرتا ہے۔ ORM لائبریریاں (Room, Realm) کلاسز کو ڈیٹا بیس ٹیبلز پر میپ کرنے کے لیے reflection استعمال کرتی ہیں۔

  • سیریلائزیشن — Gson Field.get() کے ذریعے آبجیکٹ کے اعلان شدہ فیلڈز پڑھتا ہے اور @SerializedName اینوٹیشنز کے مطابق JSON بناتا ہے۔
  • ڈیپنڈنسی انجیکشن — Dagger اینوٹیشن پروسیسنگ کے ذریعے کوڈ بناتا ہے، Koin رن ٹائم ریزولوشن کے لیے Kotlin ریفلیکشن استعمال کرتا ہے۔
  • ٹیسٹنگ — JUnit reflection کے ذریعے @Test والے میتھڈز ڈھونڈتا ہے اور کال کرتا ہے؛ Mockito dynamic proxy کے ذریعے موک بناتا ہے۔
  • ڈیٹا بیس — Room Class.getDeclaredFields() کے ذریعے کمپائل کے وقت Entity فیلڈز کی جانچ کرتا ہے (KAPT/KSP کے ذریعے)۔
  • تجزیات اور نگرانی — Firebase Crashlytics Throwable.getStackTrace() کے ذریعے اسٹیک ٹریس حاصل کرتا ہے، جو reflection پر مبنی ہے۔

ان میں سے ہر استعمال بالکل رن ٹائم میں کام کرتا ہے — کوڈ کو پہلے سے معلوم نہیں ہوتا کہ وہ کن کلاسز سے ٹکرائے گا۔ Reflection اس غیر یقینی صورتحال پر قابو پانے کے لیے ایک عالمگیر میکانزم فراہم کرتا ہے، کارکردگی اور سیکیورٹی کی قیمت پر۔

Reflection کی کارکردگی: متحرک رسائی کی قیمت

Reflection براہ راست میتھڈ کالز سے 10–100 گنا سست ہے۔ وجہ JIT اصلاحات (devirtualization, inlining) کی کمی، ہر کال پر اقسام کی جانچ اور پیرامیٹرز کو Object[]/varargs میں پیک کرنا ہے۔ Android 14 پر ART reflection کالز کو ان لائن بہتر نہیں بنا سکتا کیونکہ ہدف میتھڈ عمل کے وقت تک نامعلوم ہے۔

آپریشنبراہ راست کالReflection کے ذریعےسستی
بغیر پیرامیٹر کے میتھڈ کال~3 ns~120 ns40x
int فیلڈ پڑھنا~1 ns~85 ns85x
2 پیرامیٹرز کے ساتھ میتھڈ کال~4 ns~250 ns62x
کنسٹرکٹر کے ذریعے انسٹنس بنانا~5 ns~180 ns36x
سٹرنگ کے ذریعے کلاس کا تعین~800 ns

ڈیٹا Google Pixel 8 (Android 14, ART) پر حاصل کیا گیا۔ reflection کی کارکردگی ہر Android ورژن کے ساتھ بہتر ہوتی ہے: Android 9 پر Method.invoke() کے ذریعے کال براہ راست کال سے 150 گنا سست تھی، Android 14 پر 40 گنا۔ ART بہتری کے لیے بلٹ ان method handle میکانزم استعمال کرتا ہے۔

کارکردگی کے لحاظ سے اہم حصوں میں، ڈویلپرز reflection کو کوڈ جنریشن سے بدل دیتے ہیں: Dagger رن ٹائم تلاش کے بجائے اینوٹیشن پروسیسنگ استعمال کرتا ہے، Kotlinx.serialization KSP کے ذریعے سیریلائزرز بناتا ہے، Moshi کمپائل ٹائم codegen کے لیے @JsonClass(generateAdapter = true) اپناتا ہے۔

Reflection کے متبادل: اینوٹیشنز اور کوڈ جنریشن

انوٹیشن پروسیسنگ (KAPT, KSP) اور کوڈ جنریشن موبائل ڈیولپمنٹ میں reflection کے اہم متبادل ہیں۔ وہ میٹا ڈیٹا کے تجزیہ کو رن ٹائم سے کمپائل ٹائم تک منتقل کرتے ہیں: کوڈ ایپ شروع ہونے سے پہلے بن جاتا ہے، جس سے reflection کا بوجھ ختم ہوتا ہے اور کارکردگی بہتر ہوتی ہے۔

kotlin
// KSP: reflection کے بجائے کوڈ جنریشن
@Serializable
data class Config(
    val apiUrl: String,
    val timeout: Int
)

// KSP بغیر reflection کے ConfigSerializer بناتا ہے
fun loadConfig(json: String): Config {
    return Config.serializer().decodeFromString(json)
}

اس مثال میں @Serializable Kotlinx.serialization کا اینوٹیشن ہے۔ KSP (Kotlin Symbol Processing) سورس کوڈ کا کمپائل کے وقت تجزیہ کرتا ہے، تمام @Serializable کلاسز ڈھونڈتا ہے اور سیریلائزرز بناتا ہے۔ ایپلیکیشن کے عمل کے دوران reflection استعمال نہیں ہوتا — سیریلائزر پہلے سے مشین کوڈ میں کمپائل ہو چکا ہے۔

طریقہ کاروں کا موازنہ

کوڈ جنریشن بہتر کارکردگی، اقسام کی حفاظت اور بائنری کا چھوٹا سائز فراہم کرتا ہے (ڈیڈ کوڈ ایلیمینیشن غیر استعمال شدہ reflection ڈیپنڈنسیز کو ہٹا دیتا ہے)۔ reflection ان کاموں کے لیے ضروری رہتا ہے جہاں اقسام کمپائل کے وقت نامعلوم ہوتی ہیں: متحرک پلگ ان لوڈنگ، رن ٹائم پراکسیز، ٹیسٹ انسٹرومینٹیشن۔ Kotlin کے مطابق، KSP کے ساتھ Kotlinx.serialization reflection پر مبنی Gson سے 3–5 گنا تیز ہے۔

Android اور iOS پر Reflection کی حدود

موبائل پلیٹ فارمز پر Reflection کی سیکیورٹی اور کارکردگی کی حدود ہیں۔ Android API 28 (Pie) سے شروع کرکے non-SDK انٹرفیسز کے لیے setAccessible کو محدود کرتا ہے — پوشیدہ سسٹم میتھڈ کھولنے کی کوشش ایک استثنا یا انتباہ کا سبب بنتی ہے۔ Swift کے ساتھ iOS کلاسیکی معنوں میں reflection کو سپورٹ نہیں کرتا: Swift Mirror API صرف خصوصیات (name, value) کی پڑھائی فراہم کرتا ہے، بغیر ترمیم یا میتھڈ کالز کے۔

Google Play ان ایپلیکیشنز کو مسترد کرتا ہے جو پلیٹ فارم کی پابندیوں کو نظرانداز کرنے کے لیے reflection استعمال کرتی ہیں: سسٹم سروسز کی تبدیلی، SELinux پالیسیوں میں ترمیم، محفوظ اجازتیں پڑھنا۔ Apple بھی ان ایپلیکیشنز کو بلاک کرتا ہے جو reflection کے ذریعے پرائیویٹ APIs کو کال کرتی ہیں — App Review جانچ بائنری میں معروف پرائیویٹ سلیکٹرز کے ساتھ objc_msgSend کے سٹرنگ دستخطوں کو اسکین کرتی ہے۔

ProGuard/R8 ایک اور حد ہے۔ اوبسکیشن اور کوڈ منیفیکیشن کلاسز اور میتھڈز کو چھوٹے ناموں (a, b, c) میں تبدیل کرتے ہیں۔ اگر کوڈ Class.forName(“com.example.MyClass”) استعمال کرتا ہے، تو اوبسکیشن کے بعد یہ ٹوٹ جائے گا۔ حل proguard-rules.pro میں keep قواعد ہیں:

groovy
// reflection کے لیے ProGuard keep قواعد
-keep class com.example.** { *; }
-keep class * implements java.io.Serializable { *; }
-keepclassmembers class * {
    @com.google.gson.annotations.SerializedName ;
}
-keepattributes Signature, InnerClasses, EnclosingMethod

-keep قواعد R8 کو بتاتے ہیں کہ reflection کے ذریعے استعمال ہونے والی کلاسز کا نام نہ بدلیں۔ ان قواعد کے بغیر، اوبسکیٹڈ ایپ ClassNotFoundException کے ساتھ کریش ہوگی — رن ٹائم تبدیل شدہ سٹرنگ نام سے کلاس نہیں ڈھونڈ پائے گا۔

اکثر پوچھے جانے والے سوالات

کیا Reflection ایپلیکیشن کی کارکردگی کے لیے نقصان دہ ہے؟

ہاں، reflection براہ راست کال سے 10–100 گنا سست ہے۔ اہم وجوہات: JIT اصلاحات (inlining, devirtualization) کی کمی، پیرامیٹر پیکنگ اور ہر کال پر اقسام کی جانچ۔ پروڈکشن کوڈ کے لیے KSP یا اینوٹیشن پروسیسنگ کے ذریعے reflection کو کوڈ جنریشن سے بدلنے کی سفارش کی جاتی ہے۔

Java reflection اور Kotlin reflection میں کیا فرق ہے؟

Java reflection Class، Method، Field کے ذریعے کام کرتا ہے اور پرائیویٹ ممبرز کے لیے setAccessible کی ضرورت ہوتی ہے۔ Kotlin reflection KClass، KFunction، KProperty استعمال کرتا ہے اور sealed class، data class، کوروٹینز (suspend فنکشنز) اور null-safety کو سپورٹ کرتا ہے۔ Kotlin reflection Java reflection پر مبنی ہے لیکن ٹائپ سیف API کا اضافہ کرتا ہے۔

Reflection استعمال کرتے وقت اوبسکیشن کی مشکلات سے کیسے بچیں؟

reflection کے ذریعے استعمال ہونے والی کلاسز، میتھڈز اور فیلڈز کے لیے ProGuard/R8 keep قواعد شامل کریں۔ ہر Class.forName()، getDeclaredMethod()، getDeclaredField() کے لیے ایک مناسبت -keep ہدایت ہونی چاہیے۔ GreenDAO اور Room جیسے ٹولز خودکار طور پر keep قواعد بناتے ہیں۔

کیا Swift میں Reflection موجود ہے؟

Swift کے پاس مکمل معنوں میں reflection نہیں ہے۔ Mirror API (Swift 2+) ساخت یا کلاس کی خصوصیات پڑھنے کی اجازت دیتا ہے: نام، قدر، قسم۔ میتھڈز کو کال کرنا، فیلڈز میں ترمیم کرنا اور قسم کے لحاظ سے انسٹنسز بنانا ناممکن ہے۔ اس کے لیے NSObject سے @objc dynamic کے ساتھ وراثت کرتے وقت Objective-C Runtime استعمال ہوتا ہے۔

کون سی لائبریریاں Android پر Reflection استعمال کرتی ہیں؟

Gson (JSON سیریلائزیشن)، Retrofit (dynamic proxy کے ذریعے انٹرفیس امپلیمنٹیشن بنانا)، Mockito (موک بنانا)، Koin (ڈیپنڈنسی انجیکشن)، Room (KAPT کے ذریعے کمپائل کے وقت Entity جانچ)، Firebase Crashlytics (اسٹیک ٹریس تجزیہ)۔ زیادہ تر لائبریریاں KSP/KAPT کے ساتھ کوڈ جنریشن کی طرف بڑھ رہی ہیں۔

خلاصہ

  • Reflection کلاسز، میتھڈز اور فیلڈز کے میٹا ڈیٹا تک رسائی کے لیے رن ٹائم میکانزم ہے۔
  • Java reflection Class، Method، Field استعمال کرتا ہے؛ Kotlin کوروٹین انٹیگریشن کے ساتھ KClass، KFunction، KProperty استعمال کرتا ہے۔
  • Objective-C Runtime رسائی کی پابندیوں کے بغیر class_copyMethodList اور objc_getClass فراہم کرتا ہے۔
  • Reflection سست ہے — JIT اصلاحات کی کمی کی وجہ سے براہ راست کال سے 10–100 گنا۔
  • متبادل — کوڈ جنریشن (KSP, KAPT) اور اینوٹیشن پروسیسنگ — reflection کا بوجھ ختم کرتے ہیں۔
  • ProGuard/R8 کو Class.forName() اور getDeclaredMethod() کے ذریعے استعمال ہونے والی کلاسز کے لیے keep قواعد درکار ہیں۔
  • reflection متحرک پلگ ان لوڈنگ، DI اور ٹیسٹ فریم ورکس کے لیے ناگزیر ہے جہاں اقسام کمپائل کے وقت نامعلوم ہوتی ہیں۔

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

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

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

مزید پڑھیں