You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中继承Exception并实现GraphQLError时如何解决意外覆盖问题

解决Kotlin中ShopException继承Exception并实现GraphQLError的方法冲突问题

这个问题的核心是Java和Kotlin对方法签名的解析差异导致的冲突:

  • Java的Exception类自带public String getMessage()方法,在Kotlin中会被自动识别为val message: String?的getter方法,其JVM签名是<get-message>()。
  • 而GraphQLError接口要求实现的getMessage(): String!方法,在JVM上的签名和前者完全一致,因此触发了“Accidental override”的冲突。

解决方案:使用@JvmName注解修改方法的JVM签名

我们可以通过@JvmName注解,将实现GraphQLError接口的getMessage()方法重命名,避免和父类Exception的方法签名冲突。同时处理返回值的兼容性(Exception的message是可空类型,而GraphQLError要求非空):

import graphql.GraphQLError
import graphql.ErrorType

enum class ErrorCode {
    INVALID_INPUT,
    RESOURCE_NOT_FOUND,
    PERMISSION_DENIED
}

class ShopException(val code: ErrorCode) : Exception(code.name), GraphQLError {
    // 用@JvmName修改JVM层面的方法名,避开和Exception的getMessage()冲突
    @JvmName("getGraphQLErrorMessage")
    override fun getMessage(): String {
        // 优先使用父类的message,为空则返回ErrorCode对应的描述
        return message ?: when(code) {
            ErrorCode.INVALID_INPUT -> "输入参数无效"
            ErrorCode.RESOURCE_NOT_FOUND -> "请求的资源不存在"
            ErrorCode.PERMISSION_DENIED -> "没有操作权限"
        }
    }

    // 实现GraphQLError的其他必要方法,根据业务需求返回对应值
    override fun getLocations(): MutableList<GraphQLError.Location>? = null
    override fun getErrorType(): ErrorType? = ErrorType.ValidationError
    override fun getExtensions(): MutableMap<String, Any>? {
        return mutableMapOf("errorCode" to code.name)
    }
}

原理说明

@JvmName注解会改变该方法在JVM字节码中的名称,让它变成getGraphQLErrorMessage,这样就不会和Exception继承来的<get-message>()方法签名重复。而Kotlin编译器会自动处理接口方法的映射,确保GraphQLError的方法调用能正确指向我们重命名后的方法。

这种方式不需要修改父类Exception的任何代码,完美适配你无法控制父类字段的场景。

内容的提问来源于stack exchange,提问作者Alkis Mavridis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:18:55