I make some code to detect type model data using the "DefineTypeGeneric" class.
Main Class
fun main() {
val list = ArrayList<Any>()
list.add("Kelvin")
list.add(23)
DefineTypeGeneric<String>().checkType(list[0]) // work
DefineTypeGeneric<String>().checkType(list[1]) // work
}
DefineTypeGeneric Class
class DefineTypeGeneric<T>(private val classGeneric: Class<T>) {
companion object {
inline operator fun <reified T>invoke() = DefineTypeGeneric(T::class.java)
}
fun checkType(t: Any) {
when {
classGeneric.isAssignableFrom(t.javaClass) -> println("Correct Type")
else -> println("Wrong Type")
}
}
}
It's work for this case.
Now, I want to detect the data model type just like this case but use a function some like this.
functionGeneric
fun <T>functionGeneric(t: Any) {
DefineTypeGeneric<T>().checkType(t)
}
I call that function.
functionGeneric<String>(list[0])
But, I get error "Cannot use 'T' as reified type parameter. Use a class instead".
Error Cannot use 'T' as reified type parameter. Use a class instead
How to solve this case ?
In order to do this, you also need to make your function inline + reify the type parameter:
inline fun <reified T> functionGeneric(t: Any) {
DefineTypeGeneric<T>().checkType(t)
}
The reason for this is that your DefineTypeGeneric<T>() is actually inlined and reifies the type parameter T by using information it has on the call site (necessary to use T::class.java).
If you don't make your new functionGeneric inline as well, there is no information about T on the call site of DefineTypeGeneric<T>() (which is inside the body of functionGeneric).
As a side note, if you don't need any other feature from your DefineTypeGeneric class, you can do all of that using a single top-level inline function:
inline fun <reified T> checkType(t: Any) {
when {
T::class.java.isAssignableFrom(t::class.java) -> println("Correct")
else -> println("Wrong")
}
}
Or if the logic is more complex, one inline function and one standard function:
inline fun <reified T> checkType(t: Any) = checkType(T::class.java, t)
fun <T> checkType(target: Class<T>, t: Any) {
when {
target.isAssignableFrom(t::class.java) -> println("Correct")
else -> println("Wrong")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With