【问题标题】:Java: "attempting to assign weaker access privilege error" (Compiling JDK 1.6 Source with 1.8)Java:“试图分配较弱的访问权限错误”(Compiling JDK 1.6 Source with 1.8)
【发布时间】:2016-12-13 16:16:51
【问题描述】:

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

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

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

使用 JDK 1.6 进行编译,我们从未遇到过任何问题。 现在由于几个原因,我们不得不用 Java 8 编译我们的代码,这让我们遇到了这个问题。

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

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

对此有什么帮助吗?

【问题讨论】:

  • “我们从来没有遇到过任何问题”。但你应该拥有它们。在每个 Java 版本中,这总是被禁止的。
  • public 更改为protected(反之亦然)并不是重大的重构,即使您遇到更多此类错误。
  • 您确定您没有针对 jar 中的不同版本的类进行编译,还是什么?这听起来更像是类路径地狱,而不是 Java 8 中修复的 Java 基础。
  • 尤其是“我们从来没有遇到过任何问题”,这听起来值得研究。我会仔细看看....
  • 我只记得较旧的编译器对static 方法松懈,这已得到修复,这也是-source 1.6 没有帮助的原因,因为规则没有改变并且错误兼容性是没有尝试。但我从未听说过可以用protected 方法覆盖public abstract 方法的情况。

标签: java gradle java-8 jdk1.6


【解决方案1】:

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

Java Language Specification 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类中的print方法改成public,然后只重新编译Point类,然后用之前存在的Test的二进制执行,则不会出现链接错误,即使在编译时,公共方法被受保护的方法覆盖是不合适的(正如 Test 类无法使用这个新的 Point 类重新编译这一事实所表明的那样,除非打印已更改为 public。)(已添加重点)

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

【讨论】:

    猜你喜欢
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    相关资源
    最近更新 更多