考虑这个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 <notional> extends FooSupport implements FooInterface {}
请注意空舱体。
JLS段落意味着概念类必须格式正确,否则会发生编译错误。显然,继承公共接口方法的受保护实现的类格式不正确。
我同意可能有其他方法来指定一个交集类型,它允许FooSupport的未知子类通过用公共可见性覆盖该方法来解决上述冲突。
我认为通过概念类定义的风格是为了保持复杂性。了解简洁§4.9与其他定义的比较。
PS:另外ecj拒绝你的例子,说:
继承的方法IntersectionBug.FooSupport.foo()无法隐藏IntersectionBug.FooInterface中的公共抽象方法