【问题标题】:Illegal static interface method call非法静态接口方法调用
【发布时间】:2016-01-10 18:17:23
【问题描述】:

Java-8 允许在接口内部定义静态方法,但 restricts 它只能通过接口名称调用:

9.4: 接口可以声明静态方法,调用时不需要 引用特定对象。

例如:

interface X {
    static void y() {
    }
}

...

X x = new X() {};
x.y();

导致错误:

error: illegal static interface method call
        x.y();
            ^
  the receiver expression should be replaced with the type qualifier 'X'

在 JLS 中,此类禁令通常都有解释。在这种情况下,我没有找到任何详细信息。所以我正在寻找这个规则的全面或权威解释:为什么禁止通过特定对象引用调用静态方法?它会破坏什么?

【问题讨论】:

  • 也许更好的问题是为什么静态方法可以首先在对象引用上调用...
  • 请注意,我们如何在上面的行中获取接口 X 的实例?
  • 完全同意 @SkinnyJ 我认为 Java 开发人员正试图纠正他们所做的错误,方法是通过对象使静态可用,这有点令人困惑
  • @SkinnyJ 非常好的问题,过去一年我一直在想这个问题。我想知道这个问题是否适合 StackExchange 网站之一

标签: java java-8 jls


【解决方案1】:

一个相当强烈的共识是,类的静态方法也不应该允许有问题的语法,但是当意识到改变时为时已晚。最近添加的接口方法还为时不晚。

此外,允许这种语法会引入菱形问题的可能性,因为一个类可以实现定义碰撞方法的接口。

【讨论】:

  • 这个分析是正确的。我们认为通过实例调用静态方法的能力是一种语言设计错误,不幸的是,我们无法对类进行追溯修复。我们至少不能犯同样的错误。 (有时我们在扩展语言时确实选择故意“犯同样的错误”,选择一致性而不是局部改进——但选择涉及“嗯,改进有多好?”的判断调用在这里,差异很大够了。)
  • @Brian Goetz: ...如果新的static 接口方法比以前调用的实例方法更具体,它可能会破坏现有代码(一旦重新编译)。我想,这也是不继承static 接口方法的原因之一。接口的演变应该对现有实现的影响尽可能小。
  • @Holger ...此外,同时引入默认值和可继承的静态变量会引起更多的混乱。有很多理由在这里划清界限。
猜你喜欢
  • 2014-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多