2017-09-12 60 views
8

我有一个函数,它接受一个泛型类型的一个参数,我想访问它的类:为什么我无法获得泛型参数的类?

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

这种失败,“类文字表达有可空类型”。没关系,我理解(我可以用Any?作为我Tnull作为值)。
但是,如果我将其更改为保证这项t不是空它仍然失败,相同的错误消息:

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

在这种情况下,可以t!!::class还是捣乱?
有没有办法让不使用任何(或铸造的话)类?

回答

9

改变你的类型,以表明它是不是空的,它应该工作。您可以通过指示T需要扩展Any(而不是Any?)做到这一点。

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

不错,真不错。但是,在这种情况下't !! :: class'会有问题吗? – danielspaniol

+0

不太确定。我玩过它,并没有一个很好的解释,TBH。 – Todd

+0

@danielspaniol请参阅:https://stackoverflow.com/questions/35602231/kotlin-generics-reflection-and-the-difference-between-type-t-and-tany/35602699#35602699,'t !!'是在回答的评论中讨论。 – hotkey

2

您想使用reified类型。您可以详细了解物化类型参数herehere。代码:

inline fun <reified T : Any> test(t: T) { 
    println(T::class) 
} 
+0

你不需要这样做。您也可以像他那样将该类传递给函数 – s1m0nw1

+0

您是对的。但我不确定,他是否想要获得该特定实例的类,或者从该类型获取该类。就我个人而言,我从来没有使用':: class'函数引用来访问实体的类型。 –

4

首先,让我们来解决它

使通用型T非空的:

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

通过default,上限为Any?,而不是Any

“的默认上限(如果没有特异性ied)是任何?尖括号内只能指定一个上限。如果同一类型的参数需要不止一个上限,我们需要一个单独的WHERE子句“

侧面说明:您使用!!不当

”。但是,如果我将其更改为担保T不空......”

这是使用!!时相反,你告诉编译器,你在做什么:我不想让你检查我喜欢的类型为nulla吴春明。只需继续并调用该功能即可。我不害怕NullpointerException s。

“在这种情况下,t !! :: class仍然会引起麻烦吗?”

正如我上面所说的,它会导致许多麻烦当类型,其!!上调用,实际上是null。然后,与Java中相同,NPE将在运行时抛出。

相关问题