Scala 2.12.4无法跨包访问Java受保护静态方法问题咨询
关于Scala 2.12.4无法跨包调用Java父类protected静态方法的原因与解决办法
这个问题的核心是Scala 2.12.4对Java protected成员的访问规则做了严格的规范对齐调整,咱们一步步拆解来看:
首先得明确Java原生的protected访问规则
Java里的protected成员不是想怎么调就怎么调的,跨包子类访问时有个关键限制:只能通过子类实例、子类的this或者super来访问,不能直接通过父类的类名调用——哪怕你继承了这个父类也不行。
为什么Scala 2.12.3及更早版本可以这么做?
之前的Scala版本在处理Java的protected静态方法时,没有严格遵循JVM的访问控制规范,相当于开了个"后门",允许子类跨包直接用父类的类名调用protected静态方法。这其实是个不符合JVM规范的bug。
Scala 2.12.4为什么突然禁止了?
Scala团队在2.12.4版本里修复了这个访问控制的bug,让Scala对Java protected成员的访问逻辑完全对齐JVM标准。所以现在编译器会严格检查调用的前缀类型:你用Parent.parentMethod()调用时,前缀是Parent.type,而当前的访问上下文是Child类,两者不匹配,自然就抛出了权限错误。
针对JOOQ依赖场景的解决办法
既然JOOQ的代码生成依赖这个调用模式,你可以试试这几个方案:
- 改用子类上下文调用:因为子类继承了父类的protected静态方法,直接在子类里写
parentMethod()或者super.parentMethod()就能调用,比如修改你的Scala代码:
package child import parent.Parent class Child extends Parent { def childMethod = { println("I'm in child method and calling parentMethod") // 直接调用,利用子类继承的上下文 parentMethod() } }
- 升级JOOQ版本:JOOQ团队大概率已经针对Scala 2.12.4+的规则调整了代码生成逻辑,建议看看有没有适配新版本的JOOQ发布,升级后应该就能自动解决这个问题。
- 临时折中方案(不推荐):如果实在没法改调用方式,可以在父类所在的
parent包下写一个工具类,把parentMethod包装成public方法,然后在Scala子类里调用这个工具类。但这种方式会破坏封装,只建议作为临时过渡。
内容的提问来源于stack exchange,提问作者Teimuraz
相关产品推荐
相关产品推荐

