獲取類的所有屬性的值

鑑於 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)}")
}