Confusion about @field:Annotation

Hi! Im trying to use JVM Reflection to get the Annotations.
By doing this:

clazz.javaClass.declaredFields.forEach {
    it.trySetAccessible()
    val annotations = it.getAnnotationsByType(MyAnnotation::class.java)
    ...
}

This always comes back as empty, unless i use it with @field:MyAnnotation, why do i need the field:?

You are relying on JVM reflection and it is different that kotlin’s reflection

Kotlin does not translate 1-1 to Java.

Fields in kotlin are called properties and are translated into
multiple components, a getter, setter and a backing field (depending on the declaration)

This way, a property can be overriden, delegated and/or have a custom setter/getter

When a property is annotated, since java doesn’t have such element (kotlin properties), the annotation isn’t translated to java.
And kotlin doesn’t know what component to annotate. The getter? the setter? or the backing field?
It is needed to guide kotlin on what component should be annotated. Or rely on the default kotlin behavior.

And that is why sometimes it is needed to tell kotlin to explicitly annotate the backing field.

This is incorrect, Kotlin knows what to annotate, the rules are here:

If both property and field are valid targets for the annotation, the property is annotated, Java will hence see an annotation on the getter.

1 Like

I meant that in a metaphorical way.

Still, the annotation isn’t put on all the generated components (Specially the generated backing field) without a @field: specifier

@al3c Actually, you are right :kissing:

The following will output [true]

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

class ExampleClass {
    @ExampleAnnotation
    val exampleProperty: String = ""
}

fun main() {
    val clazz = ExampleClass::class.java
    clazz.declaredFields.forEach { field ->
        println(field.annotations.map { it is ExampleAnnotation })
    }
}

I didn’t knew about this exact behavior.

In my defense, the question was about why it is needed to add @field: and not is it always necessary.

But, I am so sorry for the false statement in my first answer