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

Kotlin运行时通过反射读取属性注解失败原因排查

问题分析与解决方案

你的问题出在两个关键地方:一是错误地获取了KProperty类自身的注解,而非目标属性的注解;二是默认情况下,你加在主构造函数参数上的注解并没有绑定到Kotlin属性本身,而是绑定到了构造函数参数上。

为什么当前代码拿不到注解?

  • 你用prop.javaClass.getAnnotations()获取的是KProperty这个类的注解(比如输出里的@kotlin.Metadata),这和你定义的MyAnnotation完全无关,属于反射对象的混淆使用。
  • 当你在主构造函数的val attr上写@MyAnnotation时,尽管你的注解@Target包含PROPERTY和VALUE_PARAMETER,但Kotlin默认会将注解应用到构造函数参数(VALUE_PARAMETER),而不是Kotlin属性(PROPERTY)。所以prop.annotations自然是空的。

解决方法一:显式指定注解应用到属性

如果你希望注解绑定到Kotlin属性本身,可以在注解前加上@property:前缀,这样就能通过KProperty.annotations直接获取:

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class MyAnnotation

class MyClass(@property:MyAnnotation val attr: List<String>)

fun main(args: Array<String>) {
    val prop = MyClass::attr
    prop.annotations.forEach { println("prop.annotations -> $it") }
    // 输出:prop.annotations -> @MyAnnotation()
}

解决方法二:从构造函数参数中获取注解

如果你需要保留注解在构造函数参数上的绑定,可以通过类的主构造函数参数列表来获取:

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class MyAnnotation

class MyClass(@MyAnnotation val attr: List<String>)

fun main(args: Array<String>) {
    // 获取主构造函数,为空则直接返回
    val constructor = MyClass::class.primaryConstructor ?: return
    // 遍历构造函数参数,输出对应注解
    constructor.parameters.forEach { param ->
        param.annotations.forEach {
            println("constructor param annotation -> $it")
        }
    }
    // 输出:constructor param annotation -> @MyAnnotation()
}

额外补充:如果你希望注解同时绑定到属性和构造函数参数,可以同时添加两个前缀:@property:MyAnnotation @MyAnnotation val attr: List<String>,这样两种反射方式都能获取到注解。

内容的提问来源于stack exchange,提问作者Jayser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:06:47