Kotlin的指定类型是否对于JVM上的原语不正确?

如果一个Kotlin函数调用引用了一个原语,比如说Int ,那么这个“被传递”的类就是盒装原语的类,而不是未装箱的版本。

 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>()) } 

这是一个错误?

这有点令人困惑,但目前的行为是通过设计。 与我们将T::class.java当作一个原始类的方法相比,这种方法有一个很大的好处。 如果函数具有类型T的参数,则其Java类在运行时始终等于T::class.java (假设T是final)。 这实际上是一个非常明智的事情:

  inline fun <reified T : Any> foo(t: T) { assert(T::class.java == t.javaClass) } 

发生这种情况的原因是,泛型类型T的参数在运行时只能有一个引用值,如果T是基本类型,则必须是装箱值。

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