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

Kotlin反射在自定义类上失效:访问父类属性触发异常

解决Kotlin反射访问父类属性时的IllegalAccessException问题

问题根源

你碰到的异常本质是:当通过子类的KClass获取继承自父类的属性时,Kotlin反射返回的是子类继承的属性引用,但底层JVM层面的访问权限校验会阻止你直接调用父类的属性getter——哪怕属性本身是public的。你的场景里,b属性实际定义在父类A中,但控制台输出显示你拿到的是B类的b属性引用,这就是问题所在。

两种可行解决方案

方案1:强制开启属性的可访问性

在调用get()方法前,给KProperty设置isAccessible = true,直接绕过JVM的访问权限检查,这是最快捷的解决方式:

fun Any.get(name: String): Any {
    println(name)
    val property = this::class.members.first { it.name == name } as KProperty1<Any, *>
    println(property)
    property.isAccessible = true // 关键代码:开启访问权限
    return property.get(this)!!
}

方案2:递归查找属性的原始定义类

如果不想用强制开启权限的方式,可以递归向上遍历父类,找到属性真正定义的那个类,再获取对应的属性引用,这样就能正常访问:

fun Any.get(name: String): Any {
    println(name)
    var currentClass = this::class
    var targetProperty: KProperty1<Any, *>? = null

    // 从当前类往上找,直到找到属性或者到Any类
    while (currentClass != Any::class) {
        targetProperty = currentClass.members.firstOrNull { it.name == name } as? KProperty1<Any, *>
        if (targetProperty != null) break
        currentClass = currentClass.superclasses.first()
    }

    // 确保找到属性,没找到就抛异常
    checkNotNull(targetProperty) { "找不到名为$name的属性" }
    println(targetProperty)
    return targetProperty.get(this)!!
}

说明

  • 方案1简单高效,是Kotlin反射处理这类权限问题的常规操作,适合大多数业务场景。
  • 方案2更严谨,避免了继承属性带来的访问歧义,适合对反射安全性有要求的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:57:30