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

Kotlin反射:安全获取对象已存在属性的实现方案问询

Kotlin安全实现按属性名动态获取属性值

我希望实现一个通用方法,当对象存在指定名称的属性时获取其值(实际业务场景更复杂,此示例简化呈现核心问题)。当前的实现需要打破型变规则,想请教是否有安全的实现方式?

当前实现代码

fun <T : Any> T.valueFor(name: String): Any? {
    val clazz = this::class as KClass<T> // <-- 为规避型变问题的不安全转换
    val prop = clazz.memberProperties.firstOrNull { name == it.name }
        ?: throw IllegalArgumentException("No property called '$name'")
    return prop.get(this) // <-- 没有上面的转换会出现编译错误
}

测试用例

@Test
fun `retrieve property`() {
    open class Animal(val color: String)
    class Dog(val name: String, color: String) : Animal(color)

    val dog = Dog("Rocky", "Yellow")
    assertThat(dog.valueFor("name")).isEqualTo(dog.name)
    assertThat(dog.valueFor("color")).isEqualTo(dog.color)

    val animal: Animal = dog
    assertThat(animal.valueFor("name")).isEqualTo(dog.name)
    assertThat(animal.valueFor("color")).isEqualTo(dog.color)

    val diffAnimal = Animal("Orange")
    assertThrows<IllegalArgumentException> { diffAnimal.valueFor("name") }
    assertThat(diffAnimal.valueFor("color")).isEqualTo(diffAnimal.color)
}

分析与安全实现方案

当前代码中this::class as KClass<T>的强制转换存在类型安全隐患:当对象是子类实例但被父类类型引用时,this::class返回的是子类的KClass,而T是父类类型,这种转换违反了型变规则,在复杂继承场景下可能引发意外错误。

方案一:安全转换属性接收者类型

去掉不安全的KClass强制转换,转而对属性的接收者类型做安全转换(由于属性来自当前对象的实际类型,该转换是安全的):

fun <T : Any> T.valueFor(name: String): Any? {
    val prop = this::class.memberProperties.firstOrNull { it.name == name }
        ?: throw IllegalArgumentException("No property called '$name'")
    @Suppress("UNCHECKED_CAST")
    return (prop as KProperty1<T, *>).get(this)
}

方案二:使用call方法绕过类型限制

利用KCallable.call方法(接收Any?类型参数),无需显式类型转换即可调用属性的获取逻辑:

fun <T : Any> T.valueFor(name: String): Any? {
    val prop = this::class.memberProperties.firstOrNull { it.name == name }
        ?: throw IllegalArgumentException("No property called '$name'")
    return prop.call(this)
}

这两种方案都保持了方法的通用性(无需提前知晓对象具体类型),同时避免了原代码中的不安全类型转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:13:16