为什么无法获取泛型参数的类?

问题描述 投票:0回答:4

我有一个函数,它接受一个泛型类型的参数,我想访问它的类:

fun <T> test(t: T) {
    t::class
}

此操作失败,并显示“类文字中的表达式具有可为空类型”。没关系,我明白(我可以使用

Any?
作为我的
T
null
作为值)。
但是,如果我将其更改为保证
t
不为空,它仍然会失败并显示相同的错误消息:

fun <T> test(t: T) {
    t!!::class
}

什么情况下

t!!::class
还会造成麻烦?
有没有一种方法可以在不使用 Any(或转换为 Any)的情况下获取类?

generics kotlin
4个回答
60
投票

更改您的类型以表明它不可为空并且它应该可以工作。您可以通过指示

T
需要扩展
Any
(而不是
Any?
)来做到这一点。

fun <T : Any> test(t: T) {
    t::class
}

11
投票

首先,让我们修复它

使泛型类型

T
不可为空:

fun <T: Any> test(t: T) {
    println(t::class)
}

默认情况下,上限是Any?

而不是
Any

“默认上限(如果未指定)是 Any?。尖括号内只能指定一个上限。如果同一类型参数需要多个上限,我们需要一个单独的 where 子句。”

旁注:您错误地使用了

!!

“但是如果我改变它以保证 t 不为空......”

不是您在使用!!

时所做的事情。相反,您告诉编译器: 
我不希望您检查我的类型是否可为空。只需继续调用该函数即可。我不怕NullpointerException
s。

“什么情况下不能!!::类仍然会造成麻烦?”

正如我上面所说,当您调用

!!

 的类型是 
null 时,它会引起麻烦。然后,与 Java 中一样,NPE 将在运行时抛出。
    


4
投票
reified

类型。您可以在

here
here了解有关具体化类型参数的更多信息。代码: inline fun <reified T : Any> test(t: T) { println(T::class) }



0
投票

这就是我的情况

class SampleEventBus<T> { fun post(event: T) { val eventType = event::class.java // But I was getting issue here subscribers[eventType]?.forEach { subscriber -> subscriber(event) } } }

我不能像
那样使用它,因为这个T将与类顶部提到的不同

fun <T: Any> post(event: T) { val eventType = event::class.java // But I was getting issue here subscribers[eventType]?.forEach { subscriber -> subscriber(event) } }

我试过这个

fun post(event: T) { event?.let{ // it: T & Any // I found this in suggestion val eventType = event::class.java // But I was getting issue here subscribers[eventType]?.forEach { subscriber -> subscriber(event) } } }

所以我将其更改为这样并且它开始工作

fun post(event: T & Any) { val eventType = event::class.java subscribers[eventType]?.forEach { subscriber -> subscriber(event) } }

© www.soinside.com 2019 - 2024. All rights reserved.