Kotlin 和 Java 中的 RuntimeException 和 GraphQLError

Posted

技术标签:

【中文标题】Kotlin 和 Java 中的 RuntimeException 和 GraphQLError【英文标题】:RuntimeException and GraphQLError in Kotlin and Java 【发布时间】:2018-12-13 13:52:22 【问题描述】:

我尝试使用 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 的 java 类时并实现 GraphQLError 我不需要覆盖 GraphQLError 中的 getMessage() 方法。

谢谢!

【问题讨论】:

我不喜欢 Kotlin,但是当我读到它时,这是 Kotlin 中尚未解决的已知问题:KT-24822(和其他) 是的,我理解这个问题,但我的问题是关于另一个事实:为什么我需要在 Kotlin 中重写 getMessage() 方法,而不是在 Java 中。 【参考方案1】:

似乎还没有无缝支持使用函数覆盖属性访问器。根据您的链接,它目前是一个错误。这可以通过一个像这样的简单示例轻松验证:

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

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

【讨论】:

【参考方案2】:

使用@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()

【讨论】:

最好解释一下您的答案以便更好地理解。 请在您的回答中添加一些解释。

以上是关于Kotlin 和 Java 中的 RuntimeException 和 GraphQLError的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 和 Java 中的 RuntimeException 和 GraphQLError

异常处理

Java 10 和 kotlin 中的“var”

Java,Swing,获取和更改所有输入字段

对kotlin和java中的synchronized的浅谈

kotlin系列之基本类型