Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

การทำงานของคีย์เวิร์ด reified ใน Kotlin

ภาพรวม

reified เป็นคีย์เวิร์ดพิเศษใน Kotlin ที่อนุญาตให้เข้าถึงข้อมูล Generic Type T ใน Runtime ได้ โดยปกติ Generic Type จะถูก Type Erasure (หายไป) ใน Runtime แต่ reified ทำให้ Compiler "เก็บ" Type Information ไว้ที่ Call Site

เงื่อนไขการใช้งาน

  • ใช้ได้เฉพาะกับ inline function เท่านั้น
  • ต้องระบุ reified ก่อน Type Parameter: inline fun ...

ตัวอย่างพื้นฐาน


inline fun  printTypeName(value: T) {
    // เข้าถึง Class ของ T ได้โดยตรง
    println("Type of value: ${T::class.java}")
    println("Simple name: ${T::class.simpleName}")
    
    // ตรวจสอบ Type
    if (T::class.java == String::class.java) {
        println("It's a String!")
    }
}

fun main() {
    printTypeName("Hello")        // Type: class java.lang.String
    printTypeName(123)            // Type: class java.lang.Integer
    printTypeName(45.67)          // Type: class java.lang.Double
    printTypeName(listOf(1,2,3))  // Type: class java.util.Arrays$ArrayList
}

การใช้งานจริง: Type Check และ Cast


inline fun  Any?.asType(): T? {
    return if (this is T) this as T else null
}

fun main() {
    val any: Any = "Hello World"
    
    // ใช้แทน any as? String
    val str: String? = any.asType()
    println(str?.uppercase()) // HELLO WORLD
    
    val num: Int? = any.asType() // null
    println(num)
}

การใช้งานจริง: JSON Deserialization (Gson/Moshi)


import com.google.gson.Gson

inline fun  fromJson(json: String): T {
    return Gson().fromJson(json, T::class.java)
}

fun main() {
    val json = """{"name":"John","age":30}"""
    
    // ไม่ต้องส่ง TypeToken หรือ Class มา
    data class User(val name: String, val age: Int)
    
    val user = fromJson(json)
    println(user) // User(name=John, age=30)
}

ข้อจำกัดของ reified

  • ❌ ไม่ใช้กับ Non-inline function ได้
  • ❌ ไม่ใช้กับ Property/Class Type Parameter ได้
  • ❌ ไม่ใช้กับ Recursive Inline Function ได้
  • ✅ ใช้กับ Type Check: value is T, T::class
  • ✅ ใช้สร้าง Instance: T::class.java.newInstance() (ต้องมี No-arg Constructor)
  • ✅ ใช้กับ Companion Object Method: T.Companion.method()

Inline Function Mechanism

เมื่อใช้ inline Compiler จะ "คัดลอก" โค้ดของ Function ไปวางที่ Call Site ทุกแห่ง ทำให้ T ถูกแทนที่ด้วย Concrete Type จริง (เช่น String, Int) ณ จุดนั้นๆ

สรุป

reified + inline = เข้าถึง Generic Type ใน Runtime ได้ เหมาะสำหรับ Library Development, Serialization, Type-safe Builders, API Client