Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 608
Grisu118 Avatar asked Oct 01 '17 13:10

Grisu118


1 Answers

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])]
like image 53
BakaWaii Avatar answered Sep 17 '22 16:09

BakaWaii