有人可以帮我绕过Kotlin编译器行为吗?
该程序的目的是将输入字符串转换为相应的类型(BMsg
或CMsg
)
并在控制台中打印结果。
但是,我从编译器收到以下消息:
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
,它与具有相同名称classA
的T
的类型参数无关。
本地方法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)
那样使用