什么是通过反射获得纯Kotlin属性注释的合法方式,它们总是丢失吗?

时间:2017-07-29 13:49:08

标签: kotlin

我试图从Kotlin数据类中获取注释

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

我需要处理类注释以生成GSON的自定义名称序列化,但无论我如何声明注释类它都不会被检测到

程序始终输出

[] 
[@some.meaningless.package.name.MyAnnotation()]

表示只存在类级别注释

2 个答案:

答案 0 :(得分:3)

正如Kotlin参考文献所述:

  

如果您未指定使用地点目标,则会根据所使用注释的@Target注释选择目标。如果有多个适用目标,则以下第一个适用的目标:param&gt; property&gt; field

要在property上注释注释,您应该使用site target,例如:

@MyAnnotation
data class TestDto(@property:MyAnnotation val answer: Int = 42)

但是,Kotlin中带有property目标的注释对Java不可见,因此您应该双重注释,例如:

@MyAnnotation      // v--- used for property  v--- used for params in Java
data class TestDto(@property:MyAnnotation @MyAnnotation val answer: Int = 42)

答案 1 :(得分:3)

确定, 似乎罪魁祸首是,Kotlin注释具有默认的 @Target(AnnotationTarget.CLASS),这在文档中并不够强调。

@Target 添加到注释类后,它现在可以正常工作

@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
annotation class MyAnnotation()

现在打印出来

[@some.meaningless.package.name.MyAnnotation()]
[@some.meaningless.package.name.MyAnnotation()]

作为一个副作用,它会强制编译器在当前版本的Kotlin中检查是否按需要应用注释,如果不存在显式@Target,则仅保留类级别注释但不执行有效性检查。