Kotlin data class: how to read the value of property if I don't know its name at compile time?

前端 未结 4 1383
南方客
南方客 2020-12-03 04:53

How can I read the value of property in a Kotlin data class instance if the property name is only known at runtime?

4条回答
  •  清歌不尽
    2020-12-03 05:31

    You can do it through reflection, and it's all the same for data classes and normal ones.

    The first option is just to use Java reflection:

    val name = obj.javaClass
                  .getMethod("getName") // to get property called `name`
                  .invoke(obj)
    

    You can even make an extension function:

    inline fun  Any.getThroughReflection(propertyName: String): T? {
        val getterName = "get" + propertyName.capitalize()
        return try {
            javaClass.getMethod(getterName).invoke(this) as? T
        } catch (e: NoSuchMethodException) {
            null
        }
    }
    

    It calls the public getter. To get a value of a private property you can modify this code using getDeclaredMethod and setAccessible. This will also work for Java objects with the corresponding getters (but it misses the convention of is and has getters for boolean).

    And usage:

    data class Person(val name: String, val employed: Boolean)
    
    val p = Person("Jane", true)
    val name = p.getThroughReflection("name")
    val employed = p.getThroughReflection("employed")
    
    println("$name - $employed") // Jane - true
    


    The second option involves using kotlin-reflect library which you should add to your project separately, here's its documentation. It will let you get actual Kotlin property value, ignoring Java getters.

    You can use javaClass.kotlin to get actual Kotlin class token, and then you get a property from it:

    val name = p.javaClass.kotlin.memberProperties.first { it.name == "name" }.get(p)
    

    This solution will work only for Kotlin classes, not for Java ones, but it is much more reliable if you need to work with Kotlin classes: it doesn't depend on the underlying implementation.

提交回复
热议问题