Kotlin: Create instance (call constructor) of generic type


Topics interesting only for Kotlin / Android / SQLite programmers

Link to this posting

Postby Ursego » 15 Dec 2019, 17:17

The problem:

You have a function with a generic type:

Code: Select all
fun <T : Animal> createAnimal() : T {
   val animal : T = Animal() as T // you mistakenly think, that T (Cat, Dog or whatever) is created...
   animal.sound() // ...and it will miauw or bark, but an Animal is created (you called its constructor, after all!), so there is no sound
   return animal
}

The solution:

To enable the solution, mark the generic parameter as reified. That is possible only in inline functions, so mark the function as inline. And instantiate (i.e. call the constructor) this way:

Code: Select all
inline fun <reified T : Animal> createAnimal() : T {
   val actualRuntimeClassConstructor : KFunction<T> = T::class.constructors.first() // get pointer to constructor of Cat, Dog or whatever
   val animal : T = actualRuntimeClassConstructor.call() // now Cat, Dog or whatever is really created!
   animal.sound() // miauw if Cat was passed, bark if Dog was passed, silent if Fish was passed :-)
   return animal
}

BTW, there is another way to do the same:

Code: Select all
inline fun <reified T : Animal> createAnimal() : T {
   val actualRuntimeClassName : String = T::class.qualifiedName!!
   val animal : T = Class.forName(actualRuntimeClassName).newInstance() as T // now Cat, Dog or whatever is really created!
   animal.sound() // miauw if Cat was passed, bark if Dog was passed, silent if Fish was passed :-)
   return animal
}
User avatar
Ursego
Site Admin
 
Posts: 143
Joined: 19 Feb 2013, 20:33



Ketones are a more high-octane fuel for your brain than glucose. Become a biohacker and upgrade yourself to version 2.0!



cron
Traffic Counter

eXTReMe Tracker