如何通过Kotlin反射获取指定返回类型的属性值?
如何通过返回类型而非属性名获取Kotlin属性值?
需求描述
无需指定属性名,仅依据返回类型获取对象的属性值。例如获取IData接口中field属性的值。
原始代码示例
interface IData { val field: String } data class Data( override val field: String ): IData val data = Data("field value") data::class.declaredMembers.forEach { member -> member::class.memberProperties.forEach { property -> if (property.returnType.classifier == String::class) { val value = // TODO } } }
已尝试的错误调用方式(均报错)
value = property.getter.invoke() // No value passed for parameter 'p1' value = property.getter.invoke(member) // Type mismatch. Required: Nothing Found: KCallable<*> value = property.invoke() // No value passed for parameter 'p1' value = property.call(data) as String // Callable expects 1 arguments, but 0 were provided. instance = member.call(data) value = property.invoke(instance) // Type mismatch. Required: Nothing Found: Any? value: String = property.get(instance) as String // Type mismatch. Required: Nothing Found: Any?
问题根源
你之前的代码逻辑绕了错误的层级:遍历declaredMembers后,又去获取member::class.memberProperties——这里拿到的是KCallable(比如属性本身)这个类的成员属性,而非目标对象data的业务属性。相当于你在操作"属性的属性",而非目标对象的实际属性,所以所有调用都会报错。
正确实现方式
直接从目标对象的类中获取成员属性列表,过滤出返回类型符合要求的属性后,调用get方法即可获取值:
interface IData { val field: String } data class Data( override val field: String ): IData val data = Data("field value") // 遍历所有成员属性(包含继承自接口的属性) data::class.memberProperties.forEach { property -> if (property.returnType.classifier == String::class) { // 调用get方法传入目标对象,获取属性值 val value = property.get(data) as String println(value) // 输出:field value } }
补充说明
- 如果只想处理当前类自己声明的属性(不包含继承的),可以用
declaredMemberProperties替代memberProperties - 也可以用
call方法获取值(因为KProperty1继承自Function1),效果和get一致:val value = property.call(data) as String
内容的提问来源于stack exchange,提问作者Viewed
相关产品推荐
相关产品推荐

