Kotlin继承含接收protected类参数方法的Java类问题求助
我之前自定义Spring AmqpAppender重写postProcessMessageBeforeSend方法时,恰好碰到过一模一样的问题!这个报错本质是Kotlin的可见性校验比Java更严格——Java允许子类重写方法时将protected的参数类型暴露为public,但Kotlin会认为这是把受保护的内部类型泄露给了外部,所以直接阻止了这个操作。
下面给你几个可行的解决办法,按推荐程度排序:
优先:将参数替换为public的父类/接口
因为Spring AmqpAppender里的这个protected类型(通常是某个Message的子类)肯定有一个public的父类或接口(比如org.springframework.amqp.core.Message)。你可以在Kotlin子类里把方法签名的参数类型换成这个public类型,然后在方法内部做类型转换来使用原有类型的功能:import org.springframework.amqp.core.Message import ch.qos.logback.classic.spi.LoggingEvent override fun postProcessMessageBeforeSend(message: Message, event: LoggingEvent): Message? { // 安全转换到目标类型,不确定的话用as?加空判断 val targetMessage = message as? YourProtectedMessageType ?: return message // 这里写你的自定义处理逻辑 targetMessage.headers["custom-tag"] = event.loggerName return targetMessage }这种方式完全符合Kotlin的可见性规则,也不会破坏原有功能,是最稳妥的方案。
如果能修改参数类型的定义:提升其可见性为public
要是这个protected的类型B是你自己编写的Java类,那直接把它的访问修饰符从protected改成public就行,这样Kotlin子类重写方法时就不会有任何限制了。不过如果B是Spring框架内部的类,这个办法就没法用了。妥协方案:抑制编译器警告
要是上面两种办法都不适用,你可以用Kotlin的注解直接跳过这个检查,但不推荐长期使用,因为它会绕过Kotlin的安全校验,可能带来潜在的可见性问题:@Suppress("PROTECTED_EXPOSED_PARAMETER") override fun postProcessMessageBeforeSend(message: YourProtectedMessageType, event: LoggingEvent): YourProtectedMessageType? { // 你的自定义逻辑 return message }
内容的提问来源于stack exchange,提问作者Nikolay Romanov

