13

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.

Grisu118
  • 339
  • 1
  • 3
  • 7
  • 1
    In case others have my version of this issue: I had a ``prop`` on an Entity object in Spring/Hiberate and the only way I could get the annotations was ``prop.javaField?.annotations`` – Colm Bhandal Jul 30 '21 at 16:45

1 Answers1

10

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])]
BakaWaii
  • 6,732
  • 4
  • 29
  • 41