Getting getters (or methods or properties) list in generic class with Kotlin

Viewed 1102

I can't figure out how should i deal with generics in kotlin.

I'm writing a history class for changes made on generic objects, which should get any type of class as parameter: after that, I would compare the old object values with the new object values, and if I found a difference, I'll write that in my data class.

I've succedeed doing that with java with bean.getClass().getMethods();, but I want to trying move to Kotlin.

class ChangeHistoryUtils<T> (val originalBean : T, username : String , var modifiedBean: T? = null) {

    data class ChangeHistory(val username: String, val fieldName : String,
                    val oldValue : String , val newValue : String , val date : LocalDate = LocalDate.now())

    fun compareBeans(){
        //how to get all originalBean getters and its values?
    }
}

I'm actually stuck here: how should obtain all the getters in my T object?

Let's guess i'll receive a class which with 10 getters, I want to call all these 10 getters in originalBean, and comparing its value with the ones in modifiedBean. If different, I will write it in my ChangeHistory

Thanks

1 Answers

You need to ensure that T itself is not a nullable type, i.e. use something like where T : Any on the class declaration, e.g.:

class ChangeHistoryUtils<T> (originalBean : T, username : String , modifiedBean: T? = null) where T : Any

If you do that you can afterwards just access the methods as you did in Java, e.g. if you just want to reuse the code you already have:

fun compareBeans(){
  originalBean::class.java.methods // this is actually your originalBean.getClass().getMethods() !
                   // just print the methods for now...
                            .forEach(::println)
}

But as you are using Kotlin you may rather want to use the Kotlin approach then, e.g. just showing the properties, or similar:

originalBean::class.memberProperties
             // again just printing them:
                       .forEach(::println)

You then need to add kotlin-reflect as dependency. You may also want to check the Kotlin reference regarding reflection.

Related