プロパティ名が実行時にしかわからない場合、Kotlinデータクラスインスタンスでプロパティの値を読み取るにはどうすればよいですか?
これは、プロパティ名を指定してクラスのインスタンスからプロパティを読み取る関数です(プロパティが見つからない場合は例外がスローされますが、その動作を変更できます ):
import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties
@Suppress("UNCHECKED_CAST")
fun <R> readInstanceProperty(instance: Any, propertyName: String): R {
val property = instance::class.memberProperties
// don't cast here to <Any, R>, it would succeed silently
.first { it.name == propertyName } as KProperty1<Any, *>
// force a invalid cast exception if incorrect type here
return property.get(instance) as R
}
使用例:
// some data class
data class MyData(val name: String, val age: Int)
val sample = MyData("Fred", 33)
// and reading property "name" from an instance...
val name: String = readInstanceProperty(sample, "name")
// and reading property "age" placing the type on the function call...
val age = readInstanceProperty<Int>(sample, "age")
println(name) // Fred
println(age) // 33
注:The org.jetbrains.kotlin:kotlin-reflect
Kotlinリフレクションを使用するには依存関係が必要です。
上記の答えは私にはうまくいかなかったので、これのための拡張関数を作成しました:
@Throws(IllegalAccessException::class, ClassCastException::class)
inline fun <reified T> Any.getField(fieldName: String): T? {
this::class.memberProperties.forEach { kCallable ->
if (fieldName == kCallable.name) {
return kCallable.getter.call(this) as T?
}
}
return null
}
これは呼び出し例です:
val valueNeeded: String? = yourObject.getField<String>("exampleFieldName")
これをアプリのbuild.gradleにも含めます。
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"