convertToSpecificMessageType

convertToSpecificMessageType

有人可以帮我绕过Kotlin编译器行为吗?
该程序的目的是将输入字符串转换为相应的类型(BMsgCMsg)
并在控制台中打印结果。
但是,我从编译器收到以下消息:


import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

abstract class classA<T> {
    fun handle(body: String) {
        val result = convertToSpecificMessageType(body) // This line fails
        printResult(result)
        otherImportantStuff()
    }

    abstract fun otherImportantStuff()

    private inline fun <reified T : Any> String.toPayloadObject(): T =
            jacksonObjectMapper().readValue(this, T::class.java)

    private inline fun  <reified T : Any> convertToSpecificMessageType(body: String): T = body.toPayloadObject()
    private fun printResult(result: T) = println("result = $result")
}

class classB : classA<BMsg>() {
    override fun otherImportantStuff() = print("important stuff of class B")
}

class classC : classA<CMsg>() {
    override fun otherImportantStuff() = print("important stuff of class C")
}

sealed class Msg
data class BMsg(val x: String) : Msg()
data class CMsg(val y: Int) : Msg()

fun main() {
    classB().handle("{\"x\" : \"aaa\"}")
    classC().handle("{\"y\" : 5}")
}

尽管我找到了解决方法-将convertToSpecificMessageType方法声明为abstract并覆盖classB / classC,我想知道(1)是什么原因使编译器抱怨
(2)是否有解决方法而不覆盖convertToSpecificMessageType
先感谢您!

P.S. kotlin版本='1.3.21'

最佳答案

通过在方法(<reified T : Any>toPayloadObject)的方法前面声明convertToSpecificMessageType,您将为您的方法引入一个新的类型参数T,它与具有相同名称classAT的类型参数无关。

本地方法T的声明将T遮盖在classA上。

结果,当您执行val result = convertToSpecificMessageType(body)时-Kotlin根本没有可用于推断其类型的上下文。尽管您使用的是classA中的方法,但T方法未使用classA中的convertToSpecificMessageType

解决方案?

您不能在类上使用修饰类型,因此:

  • 您可以删除<reified T : Any>部分并将类对象传递给
  • 方法
  • 或将其保留在此处,但是当您像val result = convertToSpecificMessageType<MyType>(body)val result : MyType = convertToSpecificMessageType(body)那样使用
  • 调用该方法时,会提供上下文

    09-25 19:37