Java 爪哇语:;试图分配较弱的访问权限错误“;(使用1.8编译JDK1.6源代码)

Java 爪哇语:;试图分配较弱的访问权限错误“;(使用1.8编译JDK1.6源代码),java,gradle,java-8,jdk1.6,Java,Gradle,Java 8,Jdk1.6,使用Gradle,我们试图编译遗留Java代码,该代码是使用JDK1.8编译器为JDK1.6开发的。 在某个时刻,编译过程会因错误而退出 试图分配较弱的访问权限;是公开的 (错误本身的原因很明显:我们在一个抽象类中有一个方法,它被声明为public,但实现类将其声明为protected。) 使用JDK1.6进行编译,我们从未遇到过任何问题。 现在出于几个原因,我们必须用Java8编译代码,让我们遇到这个问题 我们已经在构建时尝试了项目设置-PsourceCompatibility=1.6(也尝试

使用Gradle,我们试图编译遗留Java代码,该代码是使用JDK1.8编译器为JDK1.6开发的。 在某个时刻,编译过程会因错误而退出

试图分配较弱的访问权限;是公开的

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


使用JDK1.6进行编译,我们从未遇到过任何问题。 现在出于几个原因,我们必须用Java8编译代码,让我们遇到这个问题

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

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


对此有什么帮助吗?

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

第344页提供了此说明:

如果包点定义了
类点

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
中的方法
print
更改为
public
,然后仅重新编译
Point
类,然后使用先前存在的二进制文件执行
Test
,则在编译时不会发生链接错误,即使链接错误不正确,对于要由受保护的方法覆盖的公共方法(,如类
测试
无法使用此新
类重新编译,除非将打印更改为
公共
)(重点添加)


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

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

第344页提供了此说明:

如果包点定义了
类点

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
中的方法
print
更改为
public
,然后仅重新编译
Point
类,然后使用先前存在的二进制文件执行
Test
,则在编译时不会发生链接错误,即使链接错误不正确,对于要由受保护的方法覆盖的公共方法(,如类
测试
无法使用此新
类重新编译,除非将打印更改为
公共
)(重点添加)


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

“我们从来没有遇到过任何问题”。但你应该有它们。在Java的每个版本中,这都是被禁止的。将
public
更改为
protected
(或反之亦然)并不是一个重要的重构,即使您遇到了更多这样的错误。您确定您没有针对jar中的类的不同版本进行编译吗?这听起来更像是类路径地狱,而不是Java基础的东西,它在Java8中得到了修复。我会仔细看一看……我只记得较旧的编译器对
静态
方法很松懈,这是已经修复的,这就是为什么
-source 1.6
当时没有帮助的原因,因为规则没有改变,也没有尝试bug兼容性。但是我从来没有听说过用受保护的方法重写
公共摘要
方法是可能的,“我们从来没有遇到过任何问题”。但你应该有它们。在Java的每个版本中,这都是被禁止的。将
public
更改为
protected
(或反之亦然)并不是一个重要的重构,即使您遇到了更多这样的错误。您确定您没有针对jar中的类的不同版本进行编译吗?这听起来更像是类路径地狱,而不是Java基础的东西,它在Java8中得到了修复。我会仔细看一看……我只记得较旧的编译器对
静态
方法很松懈,这是已经修复的,这就是为什么
-source 1.6
当时没有帮助的原因,因为规则没有改变,也没有尝试bug兼容性。但是我从来没有听说过用
受保护的
方法重写
公共摘要
方法是可能的。