如何通过Kotlin反射修改Kotlin Object的val成员属性?
如何通过反射修改Kotlin Object中val属性的值
Kotlin的object是单例实现,其中的val属性会被编译成static final的Java字段。Java反射机制默认不允许修改final字段,这就是你遇到IllegalAccessException的原因。
要实现修改Person.foo让它返回"Biz",需要先通过反射移除字段的final修饰符,再设置新值,具体代码如下:
interface Foo { fun hello(): String } class Bar: Foo { override fun hello(): String { return "Bar" } } class Biz: Foo { override fun hello(): String { return "Biz" } } object Person { val foo: Foo = Bar() } fun main() { val person = Person val property = person::class.memberProperties.first { it.name == "foo" } val javaField = property.javaField!! // 允许访问私有字段 javaField.isAccessible = true // 移除字段的final修饰符 val modifiersField = java.lang.reflect.Field::class.java.getDeclaredField("modifiers") modifiersField.isAccessible = true modifiersField.setInt(javaField, javaField.modifiers and java.lang.reflect.Modifier.FINAL.inv()) // 设置新的Foo实现类实例 javaField.set(person, Biz()) println(Person.foo.hello()) // 输出:Biz }
注意事项:
- 这种方法依赖Java反射的内部实现,不同JVM版本可能存在兼容性问题
- 修改
final字段违背了Kotlin的不可变性设计约定,仅建议在测试、调试等特殊场景使用 - Kotlin
object的单例初始化是线程安全的,但反射修改后可能引发线程安全问题,需自行评估风险
内容的提问来源于stack exchange,提问作者tim.paetz
相关产品推荐
相关产品推荐

