Kotlin এ Reified — এটি কী, সিনট্যাক্স এবং ব্যবহার

লেখক: IT Sectr প্রকাশিত: 2026-06-21 পড়ার সময়: 8 মিনিট

reified হল Kotlin ভাষার একটি কীওয়ার্ড যা রানটাইমে inline ফাংকশনের ভিতরে জেনারিক প্যারামিটার টাইপ অ্যাক্সেস করতে দেয়। সাধারণ জেনারিক্সে টাইপ ইরেজার (টাইপ মুছে ফেলা) প্রযোগ হয় — কম্পাইল টাইমে টাইপ তথ্য মুছে যায়, কিন্তু reified এটি সংরক্ষণ করে। Kotlin Documentation, 2025 অনুযায়ী, reified শুদুমাত্র inline ফাংকশনের ভিতরে কাজ করে কারণ কম্পাইলার আসল টাইপ প্রতিস্থাপন করে ইন্লাইনিং পর্যায়ে।

মূল বিষয়সমূহ

  • reified — একটি জেনারিক প্যারামিটার মডিফায়ার যা রানটাইমে টাইপ তথ্য সংরক্ষণ করে
  • শুদুমাত্র inline — reified শুদুমাত্র inline ফাংকশনের ভিতরে কাজ করে
  • টাইপ ইরেজার — Java/Kotlin এর মানক প্রক্রিয়া যা জেনারিক টাইপ মুছে; reified এটিকে অতিক্রম করে
  • is যাঁচ — সম্ভব: if (value is String) এর পরিবর্তে if (value is T)
  • ইন্স্টেন্স তৈরি — Class<T> পাস না করে T::class.java.newInstance()

Kotlin এ reified কি?

reified হল একটি inline ফাংকশনের জেনারিক প্যারামিটারের একটি মডিফায়ার যা রানটাইমে টাইপকে বাস্তব (reify — “বাস্তবায়ন করা”) করে। reified ছাড়া, একটি জেনারিক ফাংকশনের ভিতরে টাইপ T অ্যাক্সেসযোগ্য নয় — কম্পাইলার টাইপ ইরেজার প্রয়োগ করে, সকল টাইপ তথ্য মুছে ফেলে। reified কম্পাইলারকে কল সাইটে নির্দিষ্ট টাইপ প্রতিস্থাপন করতে বাধ্য করে, যা T::class এবং is অপারেটরের মাধ্যমে অ্যাক্সেসযোগ্য হয়।

Kodee (2024) এর Kotlin জরিপ অনুযায়ী, reified টাইপ প্যারামিটার সবচেয়ে চাহিদার দশটি Kotlin বৈশিষ্ট্যের মধ্যে আছে — এগুলো ব্যবহার করেন 52% জরিপকৃত ডেভেলপার, মূলত জেনারিক ফ্যাক্টরি, DI কন্টেনার এবং সিরিয়ালাইজার লেখার জন্য। reified বিশেষ করে Gson, Moshi এবং Kotlinx Serialization এর সাথে জনপ্রিয়।

কারিগরিভাবে, প্রক্রিয়াটি সহজ: reified প্যারামিটার সহ inline ফাংকশন কল করার সময়, কম্পাইলার নির্দিষ্ট আর্গুমেন্ট টাইপ (Int, String, User) জানে এবং এটিকে T এর জায়গায় প্রতিস্থাপন করে। বাইটকোডে, reified প্যারামিটার একটি সাধারণ Class<T> এ রূপান্তরিত হয় যা একটি লুকিত আর্গুমেন্ট হিসাবে পাস করা হয়।

জেনারিক ফাংকশন লেখার জন্য reified ব্যবহার করুন যেখানে রানটাইমে টাইপ প্রয়োজন — ইন্স্টেন্স তৈরি, টাইপ যাঁচ, রিফ্লেক্শন বা সিরিয়ালাইজেশনের জন্য Class<T> প্রাপ্ত করা।

জেনারিক্সে টাইপ ইরেজার সমস্যা

টাইপ ইরেজার হল Java এবং Kotlin এর একটি প্রক্রিয়া যেখানে কম্পাইলেশনের সময় জেনারিক প্যারামিটার তথ্য মুছে ফেলা হয়। বাইটকোডে, List<String> এবং List<Int> শুদুমাত্র List হয়ে যায়। এটি Java 1.4 এর সাথে পিছনের সামঞ্জস্য রক্ষার জন্য করা হয়েছিল, যেখানে জেনারিক্স ছিল না, কিন্তু এটি রানটাইমে টাইপ নিয়ে কাজ করার সময় সীমাবদ্ধতা তৈরি করে।

kotlin
// ❌ ত্রুটি: মুছে ফেলা টাইপের ইন্স্টেন্স জাঁচ করা যাবে না
fun <T> checkType(value: Any) {
    if (value is T) { // টাইপ ইরেজার — T অজানা
        println("টাইপ ম্যাচ করে")
    }
}

// ✅ Solution: pass Class as parameter
fun <T> checkTypeWithClass(
    value: Any,
    clazz: Class<T>
) {
    if (clazz.isInstance(value)) {
        println("টাইপ ম্যাচ করে")
    }
}

উদাহরণে, checkType টাইপ ইরেজারের কারণে কম্পাইল হয় না — কম্পাইলার জানে না T এর জায়গায় কোন টাইপ প্রতিস্থাপন করতে হবে। checkTypeWithClass এ, সমস্যাটি Class<T> স্পষ্টভাবে পাস করে সমাধান করা হয়েছে, কিন্তু এতে বয়লারপ্লেট প্রয়োজন: প্রতিটি কলের সাথে .java বা ::class.java থাকে। reified এই বয়লারপ্লেট সম্পূর্ণ দূর করে।

Reified সিনট্যাক্স এবং কার্যপ্রণালী

reified মডিফায়ারটি একটি inline ফাংকশনে জেনারিক প্যারামিটারের আগে রাখা হয়। ফাংকশনটিকে inline হতে হবে — কম্পাইলারকে ইন্লাইনিং পর্যায়ে নির্দিষ্ট টাইপ প্রতিস্থাপন করতে সক্ষম হতে হবে।

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

fun main() {
    println(isA<String>("হ্যালো")) // true
    println(isA<Int>("হ্যালো"))  // false
}

কম্পাইলেশনের সময়, কল isA<String>(“Hello”) পরীক্ষা value is String এর মাধ্যমে প্রতিস্থাপিত হয়। কল isA<Int>(“Hello”) value is Int এ পরিণত হয়। টাইপটি আক্ষরিকভাবে প্রতিস্থাপিত হয়, যা is, as, ::class এবং অন্যান্য কাজ ব্যবহার করা সম্ভব করে যা টাইপ ইরেজারের সাথে উপলব্ধ নয়।

একটি reified ফাংকশন ডিকম্পাইল করা

যদি আপনি isA<String>(“Hello”) এর বাইটকোড ডিকম্পাইল করেন, তবে IntelliJ IDEA Java এ এই ফলাফল দেখাবে: String.class.isInstance(value)। একটি জেনারিক প্যারামিটারের পরিবর্তে, কম্পাইলার নির্দিষ্ট java.lang.String.class প্রতিস্থাপন করেছে — নামের মাধ্যমে টাইপ অনুসন্ধান সহ কোনো রিফ্লেক্শন নেই, শুদুমাত্র ক্লাসের একটি সরাসরি রিফারেন্স।

Reified এর সাথে টাইপ যাঁচ: is এবং as

reified এর সবচেয়ে সাধারণ ব্যবহার হল is অপারেটরের মাধ্যমে টাইপ যাঁচ করা। একটি সাধারণ জেনারিক ফাংকশনে, value is T কম্পাইল হয় না। reified এর সাথে, এটি একটি সাধারণ ক্লাসের মতো কাজ করে: value is String, value is List<Int> (প্রায় — প্যারামিটারইজড টাইপের জন্য সীমাবদ্ধতা সহ)।

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]

এক্সটেনশন ফাংকশন filterByType একটি তালিকা ফিল্টার করে, নির্দিষ্ট টাইপের উপাদান রাখে। reified ছাড়া, আপনাকে Class<String> প্যারামিটার সহ filterByType<String>(list) লিখতে হবে। reified এর সাথে, কলটি একটি তালিকায় একটি প্রাকৃতিক কর্ম হিসাবে পড়া হয়, যা ডেটা প্রক্রিয়াকরণ শৃংখলের পড়ার সুবিধা বাড়ায়।

Kotlin Coroutines Guide (JetBrains, 2025) অনুযায়ী, কোরুটিন ফলাফল টাইপ পাস করার জন্য launch এবং async এ reified টাইপ যাঁচ ব্যবহার করা হয়, যা অধিকাংশ ক্ষেত্রে স্পষ্ট টাইপ নির্দেশ এড়ায়।

Reified এর সাথে রিফ্লেক্শন: ইন্স্টেন্স তৈরি এবং Class অ্যাক্সেস

reified T::class এর অ্যাক্সেস প্রদান করে — KClass এর একটি রিফারেন্স, যেখান থেকে .java এর মাধ্যমে Java Class প্রাপ্ত করা যায়। এটি রিফ্লেক্শনের মাধ্যমে ইন্স্টেন্স তৈরির, সিরিয়ালাইজারের সাথে কাজ করার এবং রানটাইমে ক্লাস এনোটেশন প্রাপ্তির সুযোগ খুলে দেয়।

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 র্যাপার উৎপাদনে reified ব্যবহারের একটি ক্লাসিক উদাহরণ। gson.fromJson(json, User::class.java) এর পরিবর্তে, আপনি gson.fromJson<User>(json) লিখতে পারেন। এটি একটি ছোট উন্নতি মনে হতে পারে, কিন্তু শতাধিক সিরিয়ালাইজেশন কল সহ একটি প্রকল্পে, reified বয়লারপ্লেট যথেষ্ট হ্রাস করে এবং কোড পরিষ্কার করে।

Reified এর সীমাবদ্ধতা এবং বিকল্প

reified এর সীমাবদ্ধতা রয়েছে। প্রথম — এটি শুদুমাত্র inline ফাংকশনের ভিতরে কাজ করে। যদি একটি ফাংকশনকে inline করা না যায় (যেমন, এটি রিকার্সিভ বা অতিবড়), তবে reified উপলব্ধ নয়। দ্বিতীয় — reified সরাসরি suspend ফাংকশনের সাথে ব্যবহার করা যায় না, শুদুমাত্র inline র্যাপারের মাধ্যমে।

তৃতীয় — reified প্যারামিটারইজড টাইপের সাথে সম্পূর্ণ রূপে কাজ করে না। উদাহরণস্বরূপ, filterByType<List<String>>() অসাধারণ ফলাফল দিতে পারে কারণ প্যারামিটারইজড টাইপের জন্য, reified শুদুমাত্র রও টাইপ (List) সংরক্ষণ করে, জেনারিক আর্গুমেন্ট ছাড়া। সম্পূর্ণ প্যারামিটারইজড টাইপ যাঁচের জন্য, TypeToken সহ রিফ্লেক্শন প্রয়োজন।

কর্মreified সহreified ছাড়া
value is T✅ কাজ করে❌ কম্পাইল ত্রুটি
T::class✅ কাজ করে❌ কম্পাইল ত্রুটি
List<String> is T⚠️ শুদুমাত্র রও টাইপ❌ ত্রুটি
ইন্স্টেন্স তৈরি✅ রিফ্লেক্শনের মাধ্যমে❌ Class<T> প্রয়োজন
Suspend ফাংকশন❌ শুদুমাত্র inline র্যাপারের মাধ্যমে❌ প্রযোজ্য নয়

যেখানে reified উপলব্ধ নয়, সেখানে স্পষ্ট Class<T> বা লাইব্রেরি থেকে TypeToken (যেমন, Gson TypeToken বা Jackson TypeReference) সহ প্যাটার্ন ব্যবহার করুন। এই পদ্ধতি যে কোনো ফাংকশনে কাজ করে কিন্তু বয়লারপ্লেট প্রয়োজন এবং কম সুবিধাজনক।

সাধারণ জিজ্নাসা

কেন reified শুদুমাত্র inline ফাংকশনের সাথে কাজ করে?

কম্পাইলার ফাংকশন বডি ইন্লাইনিংয়ের সময় reified প্যারামিটার T কে নির্দিষ্ট টাইপে প্রতিস্থাপন করে। যদি ফাংকশনটি inline না হয়, তবে কম্পাইলারের টাইপ প্রতিস্থাপনের কোনো জায়গা নেই — একটি জেনারিক ফাংকশন কল একটি একক বাইটকোডের মাধ্যমে এগিয়ে চলে যেখানে T মুছে ফেলা হয়। ইন্লাইন প্রতিটি টাইপ আর্গুমেন্টের জন্য একটি আলাদা বাইটকোড কপি তৈরি করে।

একটি reified প্রাপার্টি ঘোষণা করা যাবে কি?

না, reified শুদুমাত্র ফাংকশন প্যারামিটারে প্রযোজ্য। প্রাপার্টির জন্য, রিটার্ন মান সহ inline fun <reified T> প্যাটার্ন ব্যবহার করুন, অথবা কংস্ট্রাক্টরের মাধ্যমে স্পষ্টভাবে Class<T> পাস করুন। এক্সটেনশন প্রাপার্টিও reified সমর্থন করে না।

reified nullable টাইপের সাথে কিভাবে কাজ করে?

reified nullable টাইপ সমর্থন করে: reified T : Any (অ-নাল) এবং শুদুমাত্র reified T (নাল হতে পারে)। nullable টাইপের জন্য, T::class অ-নাল সংস্করণের জন্য ক্লাস ফেরত (String? এর জন্য String::class)। value is T যাঁচ null কে আমান দেয়: যদি T = String?، তবে null is T = true।

reified এর কোনো ওভারহেড আছে কি?

সর্বনিম্ন। reified রিফ্লেক্শন ব্যবহার করে না — কম্পাইলার ইন্লাইনিং পর্যায়ে নির্দিষ্ট টাইপ প্রতিস্থাপন করে। বাইটকোডে, এটি একটি সরাসরি ক্লাস রিফারেন্স (ldc + checkcast/invokevirtual)। ম্যানুয়ালি Class<T> পাস করার সাপেক্ষে কোনো ওভারহেড নেই — উভয় পদ্ধতি একই বাইটকোড উৎপন্ন করে।

reified কি Android ডিভেলপমেন্টে ব্যবহার করা যাবে?

হ্যাঁ, reified Android এ সক্রিয়ভাবে ব্যবহৃত হয়। Bundle.getParcelable<T>(), Intent.getSerializableExtra<T>(), Android KTX এর viewModels<T>() — এই সকল ফাংকশন স্পষ্টভাবে Class<T> পাস করা এড়ার জন্য reified ব্যবহার করে। Google Android Docs (2025) অনুযায়ী, জেনারিক API এর জন্য reified সুপারিশ করা হয় যেখানে রানটাইমে টাইপ প্রয়োজন।

সারাংশ

  • reified — inline ফাংকশনের জন্য একটি জেনারিক প্যারামিটার মডিফায়ার যা রানটাইমে টাইপ সংরক্ষণ করে
  • টাইপ ইরেজার — মানক টাইপ মুছে ফেলার প্রক্রিয়া; reified ইন্লাইনিংয়ের মাধ্যমে এটি অতিক্রম করে
  • is/as — টাইপ যাঁচ এবং কাস্ট reified এর সাথে সাধারণ ক্লাসের মতো কাজ করে
  • ক্লাস রিফারেন্স — T::class এবং T::class.java রিফ্লেক্শন এবং সিরিয়ালাইজেশনের জন্য উপলব্ধ
  • শুদুমাত্র inline — reified inline ফাংকশন ছাড়া অসম্ভব টাইপ প্রতিস্থাপন প্রক্রিয়ার কারণে
  • প্যারামিটারইজড টাইপ — reified জেনারিক আর্গুমেন্ট সংরক্ষণ করে না (শুদুমাত্র রও টাইপ)
  • ব্যবহার — Gson/Moshi সিরিয়ালাইজেশন, DI কন্টেনার, সঙ্গ্রহে টাইপ যাঁচ, Android KTX

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন