如何检查Kotlin中的泛型类型?

and*_*ich 22 kotlin

我有课

class Generic<T : SuperType>()
Run Code Online (Sandbox Code Playgroud)

这段代码不对

fun typeCheck(s: SuperType): Unit {
            when(s){
                is T -> //do some thin
            }
        }
Run Code Online (Sandbox Code Playgroud)

但是施放s类型T s as T显示警告 - 不安全的施法.
怎么检查s是什么类型T

Kir*_*man 30

如果您需要检查某些内容是否属于泛型类型T,则需要有一个Class<T>要检查的实例.这是Java中常见的技术,但在Kotlin中我们可以使用内联工厂方法来获取类对象.

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)
}
Run Code Online (Sandbox Code Playgroud)


小智 8

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")
}
Run Code Online (Sandbox Code Playgroud)

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>
}
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*lov 7

通用类型在运行时不会在JVM上实现,因此在Kotlin中无法执行此操作.警告是正确的,因为编译器在完成强制转换时不可能生成任何失败的指令,因此取消选中强制转换,这意味着程序可能会在某个时刻或之后中断.

可能有用的相关特征是内联函数中的具体类型参数.但是,类不能具有已知的类型参数,因此如果您对用例进行详细说明,我可以尝试帮助您实现您似乎需要的内容.