获取类的所有属性的值

鉴于 Example 类扩展了 BaseExample 类并具有一些属性:

open class BaseExample(val baseField: String)

class Example(val field1: String, val field2: Int, baseField: String): 
    BaseExample(baseField) {
    
    val field3: String
        get() = "Property without backing field"

    val field4 by lazy { "Delegated value" }

    private val privateField: String = "Private value"
}

可以掌握一个类的所有属性:

val example = Example(field1 = "abc", field2 = 1, baseField = "someText")

example::class.memberProperties.forEach { member ->
    println("${member.name} -> ${member.get(example)}")
}

运行此代码将导致抛出异常。属性 private val privateField 被声明为私有,并且在其上调用 member.get(example) 将不会成功。处理此问题的一种方法是过滤掉私有属性。为此,我们必须检查属性的 Java getter 的可见性修饰符。在 private val 的情况下,getter 不存在,所以我们可以假设私有访问。

辅助函数及其用法可能如下所示:

fun isFieldAccessible(property: KProperty1<*, *>): Boolean {
    return property.javaGetter?.modifiers?.let { !Modifier.isPrivate(it) } ?: false
}

val example = Example(field1 = "abc", field2 = 1, baseField = "someText")

example::class.memberProperties.filter { isFieldAccessible(it) }.forEach { member ->
    println("${member.name} -> ${member.get(example)}")
}

另一种方法是使用反射访问私有属性:

example::class.memberProperties.forEach { member ->
    member.isAccessible = true
    println("${member.name} -> ${member.get(example)}")
}