如何获取AnnotationTarget.EXPRESSION声明的注解实例并运行时读取?
Kotlin表达式注解的运行时读取问题
核心结论:你当前的写法完全无法在运行时读取到这个注解,原因有两个:
- 你的
MyAnnotation注解使用了AnnotationRetention.SOURCE保留策略,这种注解仅在编译阶段有效,编译完成后会被直接丢弃,不会写入字节码,运行时根本找不到它的踪迹。 - 该注解的目标是
AnnotationTarget.EXPRESSION,也就是绑定在赋值的表达式1001上,而非myValue这个变量实例。就算你把保留策略改成RUNTIME,也没法通过Int类型的实例(比如myValue)获取注解——基本类型的实例本身不携带任何注解元数据。
可行的替代方案
如果需要在运行时关联值和注解信息,可以参考以下思路:
- 调整注解的目标和保留策略:把注解标注在变量上(而非表达式),同时将保留策略改为
AnnotationRetention.RUNTIME,然后通过反射读取变量的注解(注意:局部变量的反射支持有限,可能需要将变量改为类成员)。
示例修改:@Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.PROPERTY) annotation class MyAnnotation class Test { @MyAnnotation val myValue: Int = 1001 } fun printAnnotationNames(obj: Test) { obj::myValue.annotations.forEach { println(it.annotationClass.simpleName) } } - 自定义包装类封装信息:创建一个包装类,把值和对应的注解一起存储,运行时直接读取包装类的信息。
示例代码:data class AnnotatedValue<T>(val value: T, val annotations: List<Annotation>) fun main() { val myValue = AnnotatedValue(1001, listOf(MyAnnotation())) printAnnotationNames(myValue) } fun printAnnotationNames(obj: AnnotatedValue<*>) { obj.annotations.forEach { println(it.annotationClass.simpleName) } } - 编译期注解处理器:编写注解处理器,在编译阶段扫描表达式上的注解,生成额外的代码记录值与注解的关联,运行时通过生成的代码查询对应信息。
内容的提问来源于stack exchange,提问作者exbuddha
相关产品推荐
相关产品推荐

