使用Gradle,我们尝试编译遗留的Java代码,这是为JDK 1.6开发的,带有JDK 1.8编译器。 在某些时候,编译过程因错误而退出
尝试分配较弱的访问权限;是公共的
(错误本身的原因很明显:我们在抽象类中有一个方法,它被声明为公共的,但实现类声明它为受保护的。
使用 JDK 1.6 进行编译,我们从未遇到任何问题。 现在出于几个原因,我们必须使用 Java 8 编译代码,这让我们遇到了这个问题。
我们在构建时已经尝试了项目设置-PsourceCompatibility=1.6
(也是-PtargetCompatibility=1.8
),但没有效果。
目前,重构整个产品代码(预计会出现更多类似的错误)是没有选择的,因此我们正在寻找一种使用新JDK构建旧代码的解决方案。
对此有什么帮助吗?
对于您的系统曾经使用 Java 1.6 这一事实的唯一解释是,超类中的方法访问已更改为public
,而无需重新编译子类。从一开始就禁止降低子类中的可访问性。
Java 语言规范 1.6 在第 344 页提供了这样的解释:
如果包点定义了
class Point
:package points; public class Point { public int x, y; protected void print() { System.out.println("(" + x + "," + y + ")"); } }
测试程序使用:
class Test extends points.Point { protected void print() { System.out.println("Test"); } public static void main(String[] args) { Test t = new Test(); t.print(); } }
然后这些类编译并执行测试以生成输出:
Test
如果类
Point
中public
,然后仅重新编译Point
类,然后使用以前存在的二进制文件执行Test
则不会发生链接错误,即使在编译时,公共方法被受保护的方法覆盖是不恰当的(如无法使用此方法重新编译类Test
的事实所示新Point
类,除非将打印更改为public
.)(着重号后加)
如果必须使用 Java 1.8 编译器重新创建确切的行为,请将超类中的可访问性更改为protected
,编译超类和子类,然后将超类中的可访问性更改回public
,并仅编译超类。但是,在这一点上,我强烈建议更改子类以提供适当的可访问性。