如果您需要获取属性的getter/setter,有几种内置的构造方式可以使用 YourClass::propertyName。请看下面的示例。
fun main(args: Array<String>) {
val myObject = Cat("Tom", 3, 35)
println(Cat::age.getter.call(myObject))
Cat::age.setter.call(myObject, 45)
print(myObject)
}
data class Cat(var name : String, var age : Int, val height : Int)
有时您可能不知道类的确切信息(使用泛型),或需要获取属性列表,则可以使用
val <T:Any> KClass<T>.declaredMemberProperties:Collection<KProperty1<T,*>>
,它将返回所有属性,其中一些可以是可变的(var),一些是不可变的(val),您可以通过检查是否属于
KMutableProperty<*>
(通过使用
is
运算符进行过滤或使用方便的方法,例如
filterIsInstance<KMutableProperty<*>>
)来找出不可变性。
关于您的代码片段
我完全同意hotkey的观点,但现在最好使用myObject::class.declaredMemberProperties
而不是myObject.javaClass.kotlin.memberProperties
因为第二个已被弃用
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/java-class.html
data class Cat(var name : String, var age : Int, val height : Int)
@JvmStatic
fun main(args: Array<String>) {
val myObject = Cat("Tom", 3, 35)
val properties = myObject::class.declaredMemberProperties
for (p in properties.filterIsInstance<KMutableProperty<*>>()) {
val data = when (p.returnType.javaType) {
Int::class.javaPrimitiveType,
Int::class.javaObjectType -> 5
String::class.java -> "Rob"
else -> null
}
if (data != null)
p.setter.call(myObject, data)
}
println(myObject)
}
一般来说,我会考虑这种构造方式来解决类似的问题。
val myObject = Cat("Tom", 3, 35)
Cat::class.declaredMemberProperties
.filter{ it.visibility == KVisibility.PUBLIC }
.filter{ it.returnType.isSubtypeOf(String::class.starProjectedType) }
.filterIsInstance<KMutableProperty<*>>()
.forEach { prop ->
prop.setter.call(myObject, "Rob")
}
println(myObject)