对于JVM上的原语,Kotlin的具体类型是否不正确?

时间:2015-11-29 20:33:05

标签: kotlin jvm-languages

如果Kotlin函数调用重新定义了一个原语,比如说Int,那么'pass'类就是盒装原语的类,而不是未装箱的原型。

inline fun <reified T> reify() = T::class

@Test fun reified_type_doesnt_match_for_primitive() {
    assertNotEquals(Int::class, reify<Int>())
    assertNotEquals(Int::class.java, reify<Int>().java)
    assertNotEquals<Any>(Int::class, reify<Int?>())

    val nullableInt: Int? = 42
    assertNotEquals(nullableInt!!.javaClass.kotlin, reify<Int>())

    assertEquals<Any>(java.lang.Integer::class.java, reify<Int>().java)
}

@Test fun reified_type_matches_for_class() {
    assertEquals(String::class, reify<String>())
}

这是一个错误吗?

1 个答案:

答案 0 :(得分:9)

这有点令人困惑,但目前的行为是设计上的。与我们将a:hover img {background: blue;}视为原始类的方法相比,这种方法具有很大的优势。如果函数具有类型T::class.java的参数,则其Java类在运行时始终等于T(假设T::class.java是最终的)。这实际上是一件非常明智的事情:

T

这是因为泛型类型 inline fun <reified T : Any> foo(t: T) { assert(T::class.java == t.javaClass) } 的参数在运行时只能有一个引用值,如果T是基本类型,则必须是一个盒装值。

另请参阅Kotlin论坛上有关此主题的帖子:https://devnet.jetbrains.com/thread/475540