การอ่านคำอธิบายประกอบขณะรันไทม์
ดึงอินสแตนซ์ของคำอธิบายประกอบจากสิ่งที่ประกาศด้วย reflection ของ Kotlin
การอ่านคำอธิบายประกอบขณะรันไทม์ เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
ข้อกำหนดเบื้องต้น
หากต้องการอ่านคำอธิบายประกอบในขณะทำงาน คุณต้องมีสิ่งต่อไปนี้: (1) คำอธิบายประกอบที่ประกาศด้วย @Retention(RUNTIME) (2) การพึ่งพา kotlin-reflect บนเส้นทางคลาส และ (3) การอ้างอิง KClass, KFunction หรือ KProperty ไปยังองค์ประกอบที่มีคำอธิบายประกอบ
การอ่านคำอธิบายประกอบจาก KClass
เรียกใช้ annotations บน KClass เพื่อรับคำอธิบายประกอบทั้งหมดของคลาสนั้น หรือใช้ findAnnotation สำหรับชนิดข้อมูลเฉพาะ:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class Table(val name: String)
@Table(name = "users")
class UserEntity
val ann = UserEntity::class.findAnnotation<Table>()
println(ann?.name) // "users"การอ่านคำอธิบายประกอบจากคุณสมบัติ
เข้าถึงคำอธิบายประกอบบนคุณสมบัติผ่าน KProperty.annotations หรือ findAnnotation:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class Column(val name: String)
data class User(@Column("user_name") val name: String)
val prop = User::name
val col = prop.findAnnotation<Column>()
println(col?.name) // "user_name"การอ่านคำอธิบายประกอบจากฟังก์ชัน
ใช้ KFunction.findAnnotation เพื่ออ่านคำอธิบายประกอบบนฟังก์ชัน:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class Transactional
class UserService {
@Transactional
fun save(user: User) { /*...*/ }
}
val fn = UserService::save
val isTx = fn.hasAnnotation<Transactional>()
println(isTx) // trueการวนดูคุณสมบัติทั้งหมดเพื่อค้นหาคำอธิบายประกอบ
รูปแบบที่ใช้กันทั่วไปคือสแกนคุณสมบัติที่ประกาศทั้งหมดของคลาส แล้วรวบรวมคุณสมบัติที่มีคำอธิบายประกอบเฉพาะ:
fun <A : Annotation> KClass<*>.annotatedProperties(
annotationClass: KClass<A>
): List<Pair<KProperty1<*, *>, A>> =
declaredMemberProperties
.mapNotNull { prop ->
prop.findAnnotation(annotationClass)?.let { ann -> prop to ann }
}การอ่านคำอธิบายประกอบบนพารามิเตอร์
เข้าถึงคำอธิบายประกอบของพารามิเตอร์ตัวสร้างผ่าน KFunction.parameters:
class Repo(
@param:Validate(minLength = 3) val name: String
)
val ctor = Repo::class.primaryConstructor!!
val param = ctor.parameters.first()
val ann = param.findAnnotation<Validate>()
println(ann?.minLength) // 3hasAnnotation เทียบกับ findAnnotation
ใช้ hasAnnotation เพื่อตรวจสอบค่าแบบบูลีน และใช้ findAnnotation เมื่อต้องการค่าคุณสมบัติของคำอธิบายประกอบ ทั้งสองอย่างเป็นฟังก์ชันส่วนขยายจาก kotlin.reflect.full
การเดินดูโครงสร้างลำดับชั้นของคลาส
คำอธิบายประกอบบนคลาสแม่หรือส่วนติดต่อจะไม่ถูกสืบทอดโดยอัตโนมัติในรีเฟล็กชันของ Kotlin คุณต้องเดินดู KClass.superclasses หรือใช้ KClass.allSuperclasses หากต้องการคำอธิบายประกอบที่สืบทอดมา
fun KClass<*>.findAnnotationRecursive(ann: KClass<out Annotation>) =
generateSequence(this) { null } // simplified — real impl walks supers
.flatMap { it.annotations }
.firstOrNull { it.annotationClass == ann }ประสิทธิภาพ
การเรียกใช้รีเฟล็กชันทำงานช้า หากคุณสแกนคำอธิบายประกอบเมื่อเฟรมเวิร์กเริ่มทำงาน ให้แคชผลลัพธ์ไว้ในแผนที่ที่มี KClass เป็นคีย์ อย่าอ่านคำอธิบายประกอบในเส้นทางการทำงานที่มีความถี่สูงต่อคำขอหรือเฟรม
เป้าหมายตามตำแหน่งใช้งานและฟิลด์ JVM
สำหรับคำอธิบายประกอบบนคุณสมบัติที่มีเป้าหมาย @field: คำอธิบายประกอบนั้นจะอยู่บนฟิลด์สำรองของ JVM ให้เข้าถึงผ่านรีเฟล็กชันของ Java (KProperty.javaField?.annotations) แทนรายการ annotations ของ Kotlin ซึ่งครอบคลุมเฉพาะตำแหน่งการประกาศของ Kotlin เท่านั้น
ตัวอย่างเชิงปฏิบัติ: ตัวแมปออบเจ็กต์กับฐานข้อมูลอย่างง่าย
ตัวแมปออบเจ็กต์กับฐานข้อมูลขนาดเล็กอ่านคำอธิบายประกอบ @Column เพื่อสร้างรายการคอลัมน์ SQL:
fun columns(klass: KClass<*>): String =
klass.declaredMemberProperties
.mapNotNull { it.findAnnotation<Column>()?.name }
.joinToString(", ")
println(columns(User::class)) // "user_name, email"ตรวจสอบอย่างรวดเร็ว
คุณอ่านคำอธิบายประกอบเฉพาะชนิด MyAnn จาก KClass ได้อย่างไร
สรุปทบทวน: การอ่านคำอธิบายประกอบในขณะทำงาน
ประเด็นสำคัญ:
- คำอธิบายประกอบต้องมี
@Retention(RUNTIME) - ใช้
findAnnotationเพื่อรับค่าของคำอธิบายประกอบ และใช้() hasAnnotationเพื่อตรวจสอบค่าแบบบูลีน() - ใช้งานได้กับ
KClass,KFunction,KPropertyและKParameter - แคชผลการสแกนเมื่อเริ่มต้นโปรแกรมเพื่อหลีกเลี่ยงค่าใช้จ่ายต่อคำขอ
- สำหรับคำอธิบายประกอบ
@field:ให้ใช้KProperty.javaField
คำถามที่พบบ่อย
บทเรียน “การอ่านคำอธิบายประกอบขณะรันไทม์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การอ่านคำอธิบายประกอบขณะรันไทม์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การอ่านคำอธิบายประกอบขณะรันไทม์”
ดึงอินสแตนซ์ของคำอธิบายประกอบจากสิ่งที่ประกาศด้วย reflection ของ Kotlin คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การอ่านคำอธิบายประกอบขณะรันไทม์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Reflection ของ Kotlin: KClass, KFunction, KProperty
- การสร้างและกำหนดเป้าหมายคำอธิบายประกอบแบบกำหนดเอง
- การอ่านคำอธิบายประกอบขณะรันไทม์
- การตรวจสอบและการจับคู่ด้วย Reflection