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

如何在Kotlin枚举中获取vararg声明的参数值

解决Kotlin枚举vararg构造参数无法直接访问的问题

嘿,我懂你现在的麻烦——项目里的枚举已经写好不能改,而用vararg定义的构造参数又没生成可访问的属性,导致没法直接像HANDSHAKE_SUCCESS.log[0]那样拿日志内容对吧?别慌,咱们用Kotlin的反射就能搞定,完全不用动原枚举类的代码。

具体实现

咱们给StateName枚举加一个扩展属性,通过反射获取构造时传入的日志数组:

import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.full.valueParameters

val StateName.logs: Array<out String>
    get() {
        // 获取枚举的主构造函数
        val primaryConstructor = StateName::class.primaryConstructor ?: error("No primary constructor found for StateName")
        // 找到对应log的参数(vararg参数在Kotlin中会被处理为Array类型)
        val logParam = primaryConstructor.valueParameters.firstOrNull { it.name == "log" }
            ?: error("Log parameter not found in StateName constructor")
        // 通过反射获取当前枚举实例对应的log参数值
        return primaryConstructor.callBy(
            mapOf(
                primaryConstructor.instanceParameter!! to this,
                logParam to emptyArray<String>() // 这里传入空数组只是占位,反射会自动填充实际值
            )
        ) as Array<out String>
    }

使用示例

现在你就可以像操作普通数组一样访问日志内容了:

// 获取单条日志消息
val handshakeLog = StateName.HANDSHAKE_SUCCESS.logs[0]
println(handshakeLog) // 输出: message

// 遍历多条日志
StateName.AUTHORIZATION_CHECK.logs.forEach { logMsg ->
    println(logMsg) // 依次输出: message 1, message 2
}

// 判断状态是否有日志
if (StateName.FIRST_CONNECTION.logs.isEmpty()) {
    println("该状态无需输出日志")
}

补充说明

  • 这个方案完全不需要修改原StateName枚举类,完美契合你“无法修改状态实现”的限制。
  • 反射的性能开销对于枚举这种实例数量固定且极少的场景来说,几乎可以忽略不计,不用担心影响应用性能。
  • 如果担心反射的稳定性,可以把error()替换成返回空数组的逻辑,比如return emptyArray(),让代码更健壮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:52:04