I have the following Kotlin Annotation

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY_GETTER)
@Retention(AnnotationRetention.RUNTIME)
annotation class Field(val value: String)

下面的测试代码

class TestObject(@field:Field("id") val id: Long) {

  @field:Field("string")
  val string = "Hello world"

  @get:Field("prop")
  val prop get() = string
}

class AnnotationTest {

  @Test
  fun test() {
    val obj = TestObject(200L)
    for (member in obj::class.declaredMemberProperties) {
      if (member.findAnnotation<Field>() != null) {
        println(member)
      }
      println(member)
      println(member.annotations)
    }
    println("#########")
    for(member in obj.javaClass.declaredFields) {
      println(member)
      println(member.annotations)
    }
  }

}

它将打印以下输出:

val TestObject.id: kotlin.Long
[]
val TestObject.prop: kotlin.String
[]
val TestObject.string: kotlin.String
[]
#########
private final java.lang.String TestObject.string
[Ljava.lang.annotation.Annotation;@33d512c1
private final long TestObject.id
[Ljava.lang.annotation.Annotation;@515c6049

Why I can't see the Annotation with Kotlin reflection? Need to find out if the given annotation is present on fields and property getters.

推荐答案

Your annotation for prop is targeting getter, instead of calling findAnnotation on the property, you have to call it on the getter of the property.

for (member in obj::class.declaredMemberProperties) {
    if (member.getter.findAnnotation<Field>() != null) {    //add .getter
        println(member)
    }
    println(member)
    println(member.getter.annotations)    //add .getter
}

Your annotation for id and string is targeting field, so what you did in the second loop is correct. Since member.annotations returns Annotation[], you have to change it to a List before printing it.

for(member in obj.javaClass.declaredFields) {
    println(member)
    println(member.annotations.toList())  //Add .toList()
}

Output:

val TestObject.id: kotlin.Long
[]
val TestObject.prop: kotlin.String
val TestObject.prop: kotlin.String
[@Field(value=[prop])]
val TestObject.string: kotlin.String
[]
#########
private final java.lang.String TestObject.string
[@Field(value=[string])]
private final long TestObject.id
[@Field(value=[id])]

Kotlin相关问答推荐

创建具有共同父类型的两种不同类型对象的列表的最有效方法是什么?

Jetpack Compose中的数字 Select 器问题

Kotlin协程挂起继续线程

将基于注册的服务转换为流

Android Jetpack编写androidx.compose.oundation.lazy.grid.Items

Groovy Gradle文件的Kotlin类似功能

为什么会出现Kotlin.Unit错误以及如何修复它?

Rabin-Karp字符串匹配的实现(Rolling hash)

具有泛型类型的 Kotlin 密封接口不会为其子类型推断约束

关于 Kotlin 函数类型转换的问题

你怎么知道什么时候需要 yield()?

Kotlin 静态函数:伴生对象,@JvmStatic @JvmField

Kotlin - mutableMapOf() 会保留我输入的顺序

如何使用 Kotlin Coroutines 使 setOnClickListener debounce 1 秒?

Jetpack Compose State:修改类属性

如何将命令行参数传递给Gradle Kotlin DSL

禁用 IntelliJ kotlin * 导入?

封闭 lambda 的隐式参数被shadowed

Kotlin协程无法处理异常

java.lang.NoClassDefFoundError:解析失败:Lkotlin/time/MonoClock