Reputation: 17774
I'm trying to get annotations from Kotlin data class
package some.meaningless.package.name
import kotlin.reflect.full.memberProperties
annotation class MyAnnotation()
@MyAnnotation
data class TestDto(@MyAnnotation val answer: Int = 42)
fun main(args: Array<String>) {
TestDto::class.memberProperties.forEach { p -> println(p.annotations) }
println(TestDto::class.annotations)
}
I need to process class annotation to make a custom name serialization of GSON however no matter how I declare annotation class it never gets detected
The program always outputs
[]
[@some.meaningless.package.name.MyAnnotation()]
which means only class level annotations are present
Upvotes: 1
Views: 926
Reputation: 17774
Ok, it seems that the culprit was, that Kotlin annotations have default @Target(AnnotationTarget.CLASS) which is not stressed enough in documentation.
After I added @Target to the annotation class it now works properly
@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
annotation class MyAnnotation()
Now it prints out
[@some.meaningless.package.name.MyAnnotation()]
[@some.meaningless.package.name.MyAnnotation()]
As a side affect it will force the compiler to check that the annotation is applied as required, in current version of Kotlin, if explicit @Target
is not present only class level annotations are kept but no validity checks performed.
Upvotes: 4
Reputation: 30686
As Kotlin reference said as below:
If you don't specify a use-site target, the target is chosen according to the
@Target
annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following:param
>property
>field
.
To make the annotation annotated on a property
, you should use site target, for example:
@MyAnnotation
data class TestDto(@property:MyAnnotation val answer: Int = 42)
However, annotations with property
target in Kotlin are not visible to Java, so you should double the annotation, for example:
@MyAnnotation // v--- used for property v--- used for params in Java
data class TestDto(@property:MyAnnotation @MyAnnotation val answer: Int = 42)
Upvotes: 3