You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取AnnotationTarget.EXPRESSION声明的注解实例并运行时读取?

Kotlin表达式注解的运行时读取问题

核心结论:你当前的写法完全无法在运行时读取到这个注解,原因有两个:

  1. 你的MyAnnotation注解使用了AnnotationRetention.SOURCE保留策略,这种注解仅在编译阶段有效,编译完成后会被直接丢弃,不会写入字节码,运行时根本找不到它的踪迹。
  2. 该注解的目标是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:43:17