Kotlin 具体化的类型参数不能用作函数体中的类型参数

roo*_*roo 4 parameters types inline kotlin

Kotlin 中具体化的类型参数可防止类型参数擦除并允许在运行时知道类型参数。这允许以下代码按预期编译和运行:

inline fun <reified T> isA(value: Any) = value is T
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用“T”作为类型参数而不是独立时,我收到一条消息,表明它是一个已删除的类型。以下代码演示了这一点,仅用于说明目的

inline fun <reified T> isListOfA(name: String): Boolean {
    val candidate = Class.forName(name)
    return candidate is List<T>
}
Run Code Online (Sandbox Code Playgroud)

这是由于技术限制吗?如果是这样,那是什么限制?

roo*_*roo 7

显然我没有恰当地表述我的问题以获得我想要的形式的答案。这里的大多数答案都是“因为你不能在 Java 中做到这一点”的一些变体。好吧,你不能x instanceof T用 Java做,但你可以x is T用 Kotlin做。我正在寻找潜在的实际障碍而不是 Java 规则。毕竟,规则是用来打破的。

从我对这里第一个答案的评论来看,重新表述的问题是:如果objectref is T可以通过某种机制在 Kotlin 中工作,X为什么不能通过objectref is SomeClass<T>相同的机制工作?

tl;dr 回答:因为在运行时不会有Class对象SomeClass<T>

更长的答案:首先我们必须了解机制X,即为 生成instanceof字节码指令is T。该指令采用objectrefN某个类的名称C,其中N由编译器根据上下文确定。在运行时,C派生自的类N将用于计算objectref is T表达式。为了进行此评估,C必须实例化for 的类对象。因此,对objectref is SomeClass<T>then使用相同的机制N将是SomeClass<T>. 由于类型擦除,将没有类对象,SomeClass<T>因此不可能生成所需的instanceof指令,从而应用相同的机制。除此之外instanceof指令不能采用形式的名称SomeClass<T>。因此,如果 objectref is SomeClass<T>要工作,Y必须在 Kotlin 中找到并实现一些其他机制。这种机制可能存在也可能不存在。

我知道有些人可能会说这与其他一些答案是一样的。然而,无论好坏,我的学习风格是了解事物如何在金属上起作用,然后将其与抽象模型进行综合。在这种情况下,Java 泛型的擦除概念是抽象模型(或其一部分)。真的,除非我至少了解一种在工作实现中实现它的方式,否则“擦除”对我来说感觉很模糊。