关于gradle:Java:”试图分配较弱的访问特权错误”(使用1.8编译JDK 1.6 Source)

Java: “attempting to assign weaker access privilege error” (Compiling JDK 1.6 Source with 1.8)

使用Gradle,我们正在尝试编译遗留Java代码,该代码是使用JDK 1.8编译器为JDK 1.6开发的。
在某个时候,编译过程因错误

退出

attempting to assign weaker access privileges; was public

(错误原因很明显:我们在抽象类中有一个方法,该方法声明为public,但是实现类将其声明为protected。)

使用JDK 1.6进行编译,对此我们没有任何问题。
现在由于多种原因,我们不得不使用Java 8来编译代码,从而使我们遇到了这个问题。

我们已经在构建时尝试了项目设置-PsourceCompatibility=1.6(也是-PtargetCompatibility=1.8),没有任何效果。

目前,重构整个产品代码(预计会有更多类似错误)是不可行的,因此我们正在寻找一种使用新JDK构建旧代码的解决方案。

对此有任何帮助吗?


您的系统曾经使用过Java 1.6的事实的唯一解释是,超类中的方法访问已更改为public,而无需重新编译子类。从一开始就禁止降低子类的可访问性。

Java语言规范1.6在第344页提供了以下说明:

if the package points defines the class Point:

1
2
3
4
5
6
7
package points;
public class Point {
    public int x, y;
    protected void print() {
        System.out.println("(" + x +"," + y +")");
    }
}

used by the Test program:

1
2
3
4
5
6
7
8
9
class Test extends points.Point {
    protected void print() {
        System.out.println("Test");
    }
    public static void main(String[] args) {
        Test t = new Test();
        t.print();
    }
}

then these classes compile and Test executes to produce the output:

1
Test

If the method print in class Point is changed to be public, and then only the Point class is recompiled, and then executed with the previously existing binary for Test then no linkage error occurs, even though it is improper, at compile time, for a public method to be overridden by a protected method (as shown by the fact that the class Test could not be recompiled using this new Point class unless print were changed to be public.) (emphasis added)

如果必须使用Java 1.8编译器重新创建确切的行为,请将超类中的可访问性更改为protected,编译超类和子类,然后将超类中的可访问性更改回public,然后仅编译超类。但是,在这一点上,我强烈建议更改子类以提供适当的可访问性。