Javac失败,交集类型为“试图分配较弱的访问权限”

时间:2019-02-28 01:53:02

标签: javac jls

考虑以下Java程序:

public class IntersectionBug {

    public static interface FooInterface {
        public void foo();
    }

    public static class FooSupport {
        protected void foo() {
        }
    }

    public static class Whatever<T extends FooSupport & FooInterface> {
    }
}

在JDK 1.8编译器下无法编译:

$ javac IntersectionBug.java
IntersectionBug.java:12: error: foo() in FooSupport cannot implement foo() in FooInterface
    public static class Whatever<T extends FooSupport & FooInterface> {
                                 ^
  attempting to assign weaker access privileges; was public
1 error

很明显,如果某个类型T既是FooSupport也是FooInterface,则它必须具有public void foo(),因此错误是虚假的。

我的问题:这是编译器错误,还是JLS确实指定该程序无效?如果是后者,为什么这里的次优JLS行为呢?

1 个答案:

答案 0 :(得分:0)

JLS §4.9通过名义类的概念定义了路口类型及其成员。在您的特定情况下,概念类为:

class <notional> extends FooSupport implements FooInterface {}

请注意空的班级正文。

JLS段落旨在暗示概念类必须格式正确,否则会发生编译错误。显然,为公共接口方法继承受保护的实现的类的格式不正确。

我同意,还有 种其他方式可以指定允许使用FooSupport未知子类的交集类型,该子类可以通过以公共可见性覆盖该方法来解决上述冲突。

我相信选择通过概念类进行定义的样式是为了避免复杂性。看看§4.9与其他定义相比有多简洁。

PS:ecj也拒绝您的示例,说:

  

继承的方法IntersectionBug.FooSupport.foo()无法在IntersectionBug.FooInterface中隐藏公共抽象方法