使用 obj::class.declaredMemberProperties 查找字段注释

lat*_*ell 3 reflection annotations kotlin

id在下面的测试中, class 的字段TestData被标注了注解Foo.annotations为什么and的输出是.findAnnotation<Foo>()空的?

如何检查某个字段是否被某个注解所注解?

(这与How to list field Annotations in Kotlin?不是同一个问题,询问者忘记将保留更改为 RUNTIME)

import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.findAnnotation
import kotlin.test.Test

class MissingAnnotationTest {

    @Target(AnnotationTarget.FIELD)
    @Retention(AnnotationRetention.RUNTIME)
    annotation class Foo

    data class TestData(@field:Foo val id: Int)

    @Test
    fun test() {
        val obj = TestData(123)
        val idProp = obj::class.declaredMemberProperties.first { it.name == "id" }
        println("1 name: " + idProp) // "val ...TestData.id: kotlin.Int"
        println("1 annotations: " + idProp.annotations) // [] - but why?
        println("1 found @Foo: " + idProp.findAnnotation<Foo>()) // null - but why?
    }

}
Run Code Online (Sandbox Code Playgroud)

lat*_*ell 6

我在 Kotlin 讨论组中得到了提示,现在可以自己回答:

Kotlin“属性”被编译为支持字段及其 getter/setter 函数。如果使用目标 FIELD 而不是 PROPERTY,则注释将应用于支持字段。不过,Kotlin 中不存在纯支持字段,因此必须通过 .javaField 访问它们:

val idField = obj::class.memberProperties.first { it.name == "id" }.javaField!!
assertNotNull(idField.getAnnotation(Foo::class.java))
Run Code Online (Sandbox Code Playgroud)