tufekoi
tufekoi

Reputation: 991

Call class' constructor by reflection with Kotlin

I have the following data class

data class Person (val id: Int? = null, val name: String, val active: Boolean)

I need to call it's constructor by reflection. I tried the following code

private fun <T> createEntity(constructor: Constructor<*>, vararg args: T) : Any {
    return constructor.newInstance(args)
}

and call it with an array for the args parameter.

val fields = entity.declaredFields
var elements = Array<Any>(getFieldsCount(fields), { i ->
    val index = cursor.getColumnIndex(fields[i].name.toUpperCase())
    when (fields[i].type) {
        kotlin.Int::class.java -> cursor.getInt(index)
        kotlin.Boolean::class.java -> if (cursor.getInt(index) == 1) true else false
        else -> cursor.getString(index)
    }

})
val test = createEntity(entity.constructors.first(), *elements)

With entity: Class<T> and cursor: Cursor from a local database Kotlin Documentation says :

When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *)

but even with the * I keep getting the following exception :

java.lang.IllegalArgumentException: Wrong number of arguments; expected 3, got 1

Can anyone give me some tips on how to instantiate my class? Thanks

Upvotes: 16

Views: 13214

Answers (1)

Michael
Michael

Reputation: 54725

You have to use the spread operator when invoking the newInstance() method. And the signature of createEntity() is wrong. I would recommend define it like that.

private fun <T> createEntity(constructor: Constructor<T>, vararg args: Any) : T {
    return constructor.newInstance(*args)
}

Upvotes: 12

Related Questions