How to check generic type in Kotlin?

前端 未结 4 668
温柔的废话
温柔的废话 2020-12-29 21:47

I have class

class Generic()

and this code is\'t correct

fun typeCheck(s: SuperType): Unit {
               


        
相关标签:
4条回答
  • 2020-12-29 22:17

    Generic types are not reified on the JVM at runtime, so there's no way to do this in Kotlin. The warning is correct because the compiler can't possibly generate any instruction that will fail when the cast is done, so the cast is unchecked, meaning that the program may or may not break at some point later instead.

    A related feature which might be of use is reified type parameters in inline functions. Classes can't have reified type parameters though, so if you elaborate a bit more on your use case, I can try helping you achieve what you seem to need.

    0 讨论(0)
  • 2020-12-29 22:18

    If you need to check if something is of generic type T you need to to have an instance of Class<T> to check against. This is a common technique in Java however in Kotlin we can make use of an inlined factory method that gets us the class object.

    class Generic<T : Any>(val klass: Class<T>) {
        companion object {
            inline operator fun <reified T : Any>invoke() = Generic(T::class.java)
        }
    
        fun checkType(t: Any) {
            when {
                klass.isAssignableFrom(t.javaClass) -> println("Correct type")
                else -> println("Wrong type")
           }
    
        }
    }
    
    fun main(vararg args: String) {
        Generic<String>().checkType("foo")
        Generic<String>().checkType(1)
    }
    
    0 讨论(0)
  • 2020-12-29 22:30

    This is also example.

    inline fun <reified T: ApiResponse> parseJson(body: String): T {
        // handle OkResponse only
        val klass = T::class.java
        if (klass.isAssignableFrom(OkResponse::class.java)) {
            return T::class.java.newInstance()
        }
        // handle others
        return gson.from(body, T::class.java)
    }
    
    0 讨论(0)
  • 2020-12-29 22:33

    I know that I'm kinda late to this thread, but I just want to recap on the answer provided by Alexander Udalov.

    It is, indeed, impossible to determine the type of a generic parameter in Kotlin unless you're using inline functions and declaring the generic type as reified.

    Not sure if I'll be able to answer this question entirely and accurately, but I feel like my contribution might still be valuable for someone who is attempting to do just that. So let's say you have a few data classes, and you want to check which type you're dealing with.

    You could use a function like that:

    inline fun <reified T> checkType() = when (T::class) {
        TypeA::class -> println("TypeA")
        else -> println("Type not recognized")
    }
    

    however, functions that call it must also be inline, so you might have to write something like

    inline fun <reified T> someOtherFunction(data: T) {
        checkType<T>
    }
    

    however, if you cannot allow for an inline function (let's say in an interface!), you can kinda 'cheat' the system by saying, for example

    class AmazingTypes {
        inline fun <reified T> checkType(genericParameter: T) = when (T::class) {
            TypeA::class -> println("TypeA")
            else -> println("Type not recognized")
        }
    }
    
    
    fun myAwesomeMethod(someParameter: Any) {
        val amazingClass = AmazingClass()
        amazingClass.checkType(someParameter)
    }
    
    0 讨论(0)
提交回复
热议问题