Kotlin和Java中的运行时异常和图形错误

g6ll5ycj  于 2023-01-09  发布在  Kotlin
关注(0)|答案(3)|浏览(125)

我尝试使用GraphQL和Kotlin开发REST API,但遇到了以下问题:我尝试创建一个自定义异常来扩展RuntimeException并实现GraphQLError,但在Kotlin中我无法这样做,因为我收到了以下消息:Accidental override when using third party Java interface and extending RuntimeException in kotlin.
我通过为CustomException创建一个Java类来解决这个问题。
但我不知道为什么,当我创建一个扩展RuntimeException并实现GraphQLError的kotlin类时,我需要覆盖GraphQLError中的getMessage()方法,但当我创建一个扩展RuntimeException并实现GraphQLError的java类时,我不需要覆盖GraphQLError中的getMessage()方法。
谢谢大家!

qnakjoqk

qnakjoqk1#

使用@JvmField对消息进行注解,例如:

class MyError(@JvmField override val message: String?, private val invalidField: String? = null) : RuntimeException(message), GraphQLError {

    override fun getMessage(): String = super.message ?: "no error message set"

    override fun getLocations(): List<SourceLocation> = emptyList()

    override fun getErrorType(): ErrorType = ErrorType.DataFetchingException

    override fun getExtensions(): Map<String, Any> = if(invalidField!=null)
        Collections.singletonMap<String, Any>("invalidField", invalidField)
    else
        Collections.emptyMap()
}
u91tlkcl

u91tlkcl2#

看起来用函数重写属性访问器还没有得到恰当的支持。根据你的链接,这是一个bug。这可以通过一个简单的例子很容易地验证,比如:

class Sample(val message : String) {
    fun getMessage() :String = "MyString"
}

这是因为属性message(在您的示例中,消息来自Throwable)和getMessage函数(在你的情况下,GraphQL中的getMessage)转换为相同的JVM签名。在我看来,目前的现状是属性访问器没有被视为单独的成员,因此它们不能被成员函数覆盖,甚至不能实现抽象函数。我不知道为什么会这样。

zsbz8rwp

zsbz8rwp3#

@Kisschr answer不起作用了。你必须在@JvmField旁边添加另一个注解,这样你的代码看起来就像这样:

class MyError(
    @JvmField 
    @Suppress("INAPPLICABLE_JVM_FIELD")
    override val message: String?, 
    private val invalidField: String? = null
) : RuntimeException(message), GraphQLError {

    override fun getMessage(): String = super.message ?: "no error message set"

    override fun getLocations(): List<SourceLocation> = emptyList()

    override fun getErrorType(): ErrorType = ErrorType.DataFetchingException

    override fun getExtensions(): Map<String, Any> = if(invalidField!=null)
        Collections.singletonMap<String, Any>("invalidField", invalidField)
    else
        Collections.emptyMap()
}

这个错误是由已知的Kotlinissue引起的,kotlin属性没有覆盖消息的RuntimeException getter。所以你必须告诉kotlin不要为这个属性生成getter。

相关问题