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

如何检查Kotlin中的泛型类型?,kotlin,Kotlin,我有课 class Generic<T : SuperType>() 但是将s转换为键入Ts作为T显示警告-不安全转换。 如何检查s是否为类型T?在运行时JVM上没有具体化泛型类型,因此在Kotlin中无法实现这一点。警告是正确的,因为编译器不可能生成任何在强制转换完成时将失败的指令,因此强制转换被取消选中,这意味着程序可能会或可能不会在稍后某个时间中断 内联函数中可能会用到一个相关的特性。但是类不能有具体化的类型参数,因此如果您对用例进行详细说明,我可以尝试帮助您实现您似乎需要的

我有课

class Generic<T : SuperType>()
但是将
s
转换为键入
T
s作为T
显示警告-不安全转换。

如何检查
s
是否为类型
T

在运行时JVM上没有具体化泛型类型,因此在Kotlin中无法实现这一点。警告是正确的,因为编译器不可能生成任何在强制转换完成时将失败的指令,因此强制转换被取消选中,这意味着程序可能会或可能不会在稍后某个时间中断


内联函数中可能会用到一个相关的特性。但是类不能有具体化的类型参数,因此如果您对用例进行详细说明,我可以尝试帮助您实现您似乎需要的功能。

如果您需要检查某个对象是否属于泛型类型
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)
}
class通用(val-klass:class){
伴星{
内联运算符fun invoke()=泛型(T::class.java)
}
趣味支票类型(t:任何){
什么时候{
isAssignableFrom(t.javaClass)->println(“正确类型”)
else->println(“错误类型”)
}
}
}
主要乐趣(vararg args:String){
Generic().checkType(“foo”)
泛型().checkType(1)
}

我知道我在这方面有点晚了,但我只想回顾一下Alexander Udalov提供的答案

事实上,除非使用内联函数并将泛型类型声明为
具体化
,否则无法确定Kotlin中泛型参数的类型

我不确定我是否能够完整准确地回答这个问题,但我觉得我的贡献对那些试图这样做的人来说仍然是有价值的。假设您有一些数据类,并且您想检查您正在处理的是哪种类型

您可以使用这样的函数:

inline fun checkType()=when(T::class){
TypeA::class->println(“TypeA”)
else->println(“无法识别类型”)
}
然而,调用它的函数也必须是内联的,所以您可能需要编写类似于

内联函数(数据:T){
支票类型
}
但是,如果您不能允许内联函数(比如在接口中!),您可以通过以下方式“欺骗”系统:例如

class-AmazingTypes{
inline fun checkType(genericParameter:T)=何时(T::class){
TypeA::class->println(“TypeA”)
else->println(“无法识别类型”)
}
}
fun myAwesomeMethod(someParameter:Any){
val amazingClass=amazingClass()
amazingClass.checkType(someParameter)
}
这也是一个例子

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)
}
json(body:String):T{
//仅处理OK响应
val klass=T::class.java
if(klass.isAssignableFrom(OkResponse::class.java)){
返回T::class.java.newInstance()
}
//处理他人
返回gson.from(body,T::class.java)
}

String是最终的,你为什么要使用
T:String
?@cypreshis它只是一个例子,你能回答我的问题吗?好把戏!当
Generic
类是抽象类时,您知道如何使它工作吗?我遇到的问题是在
invoke
操作符上实例化子对象。这不太容易。子类构造函数需要将
实例传递给超级构造函数。
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)
}