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
相关产品推荐
相关产品推荐

