Javac 在交集类型上失败并显示 "attempting to assign weaker access privileges"

Javac fails with "attempting to assign weaker access privileges" on intersection type

考虑这个 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 行为不是最理想的?

JLS §4.9 通过 名义 class 的概念定义交叉点类型及其成员。在您的特定情况下,名义上的 class 是:

class <notional> extends FooSupport implements FooInterface {}

请注意空 class 正文。

JLS 段落意在暗示名义上的 class 必须格式正确,否则会出现编译错误。显然,继承 public 接口方法的受保护实现的 class 格式不正确。

我同意 可能 有其他方法可以指定交集类型,允许 FooSupport 的未知子 classes 通过覆盖具有 public 可见性的方法。

我相信选择概念性 class 的定义风格是为了避免复杂性。看看 §4.9 与其他定义相比有多简洁。

PS: ecj 也拒绝了你的例子,说:

The inherited method IntersectionBug.FooSupport.foo() cannot hide the public abstract method in IntersectionBug.FooInterface