我知道如何在 Kotlin 中反射和迭代单个对象的属性以查找特定类型的所有属性:
object Obj1{
val obj1Int = 1
val obj1String = "one"
}
fun main(){
// filter out the integer property, keep the string property
Obj1::class
.declaredMemberProperties
.mapNotNull { it.get(Obj1) as? String }
.forEach { println(it) } // prints "one", does not print "1"
}
但是当我有通用对象列表时,我很难让它工作:
object Obj1{
val obj1Int = 1
val obj1String = "one"
}
object Obj2{
val obj2Int = 2
val obj2String = "two"
}
fun main() {
listOf(Obj1, Obj2).forEach {obj ->
obj::class.declaredMemberProperties
.mapNotNull { it.get(obj) as? String }
.forEach { println(it) }
}
}
it.get(obj)
有错误:Type mismatch: inferred type is Any but Nothing was expected
我该怎么做?
发生这种情况是因为编译器无法理解您从与您获取属性的对象完全相同的对象中获取属性值。它不会跟踪您在这两个地方都使用了
obj
。因此,它不允许此操作,因为它不确定 obj
是否具有所需的属性。
我们知道
obj
保证具有该属性,并且代码是安全的,我们可以强制转换该属性。这将是未经检查的演员阵容:
@Suppress("UNCHECKED_CAST")
(it as KProperty1<Any, *>).get(obj) as? String
您的第一个示例有所不同,因为您从非常特定的类型
Obj1
获取了属性,并且编译器可以验证您然后使用相同的Obj1
来获取值。