Grisu118
Grisu118

Reputation: 369

Kotlin get Field Annotation always empty

I have the following Kotlin Annotation

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

And the following Test Code

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)
    }
  }

}

It will print the following Output:

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.

Upvotes: 14

Views: 12284

Answers (1)

BakaWaii
BakaWaii

Reputation: 6992

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])]

Upvotes: 10

Related Questions