Kotlin的类型化类型对于JVM上的原语是否不正确? [英] Are Kotlin's reified types incorrect for primitives on the JVM?

查看:87
本文介绍了Kotlin的类型化类型对于JVM上的原语是否不正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果Kotlin函数调用对原语进行身份化,例如Int,则"passed"类是盒装原语的类,而不是非盒装版本的类.

If a Kotlin function invocation reifies a primitive, say Int, the 'passed' class is that for the boxed primitive, not the unboxed version.

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是最终的).这实际上是一件很明智的事情:

This is somewhat confusing, but the current behavior is by design. This approach has a major benefit compared to the one where we would treat T::class.java as a primitive class. If the function has a parameter of type T, its Java class is always equal to T::class.java at runtime (assuming T is final). This is actually a very sensible thing to expect:

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

之所以会发生这种情况,是因为泛型类型T的参数只能在运行时具有参考值,如果T是原始类型,则该参数值必须为盒装值.

This happens because the parameter of a generic type T can only have a reference value at runtime, which is necessarily a boxed value if T is a primitive type.

也可以在Kotlin论坛上查看有关此主题的主题: https://devnet.jetbrains.com/线程/475540

Also see a thread on the Kotlin forum on this subject: https://devnet.jetbrains.com/thread/475540

这篇关于Kotlin的类型化类型对于JVM上的原语是否不正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆