【问题标题】:Wrong inference for reified type parameter in KotlinKotlin 中具体类型参数的错误推断
【发布时间】:2017-09-29 07:17:51
【问题描述】:

在 Kotlin 中给出以下代码:

import com.fasterxml.jackson.module.kotlin.*

data class MyReply<R> (
        val results : Array<R>? = null
)

class ErrorClient() {
    val JSON = jacksonObjectMapper()

    inline fun<reified R> request(): Array<R>? {
        val json_in = """{"results": [2]}"""
        val res: MyReply<R> = JSON.readValue(json_in)
        return res.results
    }

    fun read(): Array<Int>? {
        val res: Array<Int>? = request()
        return res
    }
}

以及以下测试:

import org.junit.Test

class ErrorTest {
    val client = ErrorClient()

    @Test
    fun `direct`() {
        val res: Array<Int>? = client.request()
        println(res)
    }

    @Test
    fun `indirect`() {
        val res : Array<Int>? = client.read()
        println(res)
    }
}

简短的故事:第一次测试通过,第二次失败。为什么?

长话短说:当通过read() 类方法调用内联函数时,我遇到了具体参数R 的错误类型推断,但直接调用request() 有效。在间接情况下,类型被错误地推断为 java.lang.Object,因此测试失败

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
    at ErrorClient.read(Error.kt:17)
    at ErrorTest.indirect(ErrorTest.kt:14)

【问题讨论】:

    标签: kotlin kotlin-reified-type-parameters


    【解决方案1】:

    这与reified 无关。我用

    测试代码
    val res: MyReply<R> = MyReply()
    

    它不会抛出任何错误。这个问题是你的JSON.readValue 返回一个Object 而不是Integer。 Kotlin 尝试将其转换为 Integer,但失败了。

    【讨论】:

    • 那只是通过,因为 MyReply().results 为 null,可以转换为任何类型
    • @AdamSzalkowski 这就是答案。您的 JSON.readValue 不会返回 Integer。如果你用val res: MyReply&lt;R&gt; = MyReply(arrayOf(1)) as MyReply&lt;R&gt; 硬投它,它仍然可以通过。很明显JSON.readValue是错的。
    • 我的问题是,在“直接”情况下,它确实返回 Int,而在“间接”情况下,它返回 Object。为什么?
    • request() 中设置断点时,我观察到以下内容:直接:res$iv = {MyReply@2020} "MyReply(results=[2])"results = {Integer[1]@2032}0 = {Integer@2033} 2value = 2 间接:res$iv = {MyReply@2068} "MyReply(results=[2])"results = {Object[1]@2072}0 = {Integer@2033} 2@9876543 /跨度>
    • 所以根据调用它是 MyResult 或 MyResult
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多