ภาพรวม
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