Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Cannot use T as a reified type parameter" when make function to detect type model data

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 ?

like image 273
Kelvin Herwanda Tandrio Avatar asked Jun 04 '26 09:06

Kelvin Herwanda Tandrio


1 Answers

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")
    }
}
like image 62
Joffrey Avatar answered Jun 08 '26 00:06

Joffrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!