编辑:从Java 8开始,静态方法现在被允许出现在接口中。

下面是例子:

public interface IXMLizable<T>
{
  static T newInstanceFromXML(Element e);
  Element toXMLElement();
}

当然这行不通。但为什么不呢?

其中一个可能的问题是,当你调用:

IXMLizable.newInstanceFromXML(e);

在这种情况下,我认为它应该只调用一个空方法(即{})。所有子类都必须实现静态方法,所以在调用静态方法时它们都没问题。那为什么不可能呢?

编辑:我想我正在寻找比“因为这就是Java”更深刻的答案。

静态方法不能被覆盖是否有特殊的技术原因?也就是说,为什么Java的设计者决定让实例方法可重写,而不是静态方法?

编辑:我的设计的问题是我试图使用接口来执行编码约定。

也就是说,接口的目标有两个:

我希望IXMLizable接口允许我将实现它的类转换为XML元素(使用多态性,工作正常)。 如果有人想创建实现IXMLizable接口的类的新实例,他们总是知道会有一个newInstanceFromXML(Element e)静态构造函数。

除了在界面中添加注释之外,还有其他方法可以确保这一点吗?


当前回答

如果没有泛型,静态接口是无用的,因为所有静态方法调用都是在编译时解析的。所以,它们没有真正的用处。

对于泛型,它们可以使用——无论是否使用默认实现。显然需要重写等等。然而,我的猜测是,这样的用法不是很面向对象(正如其他答案迟钝地指出的那样),因此被认为不值得付出努力来有效地实现它们。

其他回答

假设你能做到;想想这个例子:

interface Iface {
  public static void thisIsTheMethod();
}

class A implements Iface {

  public static void thisIsTheMethod(){
    system.out.print("I'm class A");
  }

}

class B extends Class A {

  public static void thisIsTheMethod(){
    System.out.print("I'm class B");
  } 
}

SomeClass {

  void doStuff(Iface face) {
    IFace.thisIsTheMethod();
    // now what would/could/should happen here.
  }

}
Why can't I define a static method in a Java interface?

接口中的所有方法都是显式抽象的,因此不能将它们定义为静态方法,因为静态方法不能抽象。

我认为java没有静态接口方法,因为你不需要它们。你可能认为你知道,但是… 你会如何使用它们?如果你想叫他们

MyImplClass.myMethod()

那么就不需要在接口中声明它了。如果你想叫他们

myInstance.myMethod()

那么它就不应该是静态的。 如果您实际上打算使用第一种方法,但只是想强制每个实现都有这样的静态方法,那么它实际上是一种编码约定,而不是实现接口的实例和调用代码之间的契约。

接口允许您在实现接口的类实例和调用代码之间定义契约。java帮助您确保这个契约没有被违反,因此您可以依赖它,而不必担心哪个类实现了这个契约,只要“某个签署了契约的人”就足够了。在静态接口的情况下,你的代码

MyImplClass.myMethod()

不依赖于每个接口实现都有此方法的事实,因此不需要Java来帮助您确定使用它。

First, all language decisions are decisions made by the language creators. There is nothing in the world of software engineering or language defining or compiler / interpreter writing which says that a static method cannot be part of an interface. I've created a couple of languages and written compilers for them -- it's all just sitting down and defining meaningful semantics. I'd argue that the semantics of a static method in an interface are remarkably clear -- even if the compiler has to defer resolution of the method to run-time.

其次,我们使用静态方法意味着有一个包含静态方法的接口模式的正当理由——我不能代表你们,但我经常使用静态方法。

The most likely correct answer is that there was no perceived need, at the time the language was defined, for static methods in interfaces. Java has grown a lot over the years and this is an item that has apparently gained some interest. That it was looked at for Java 7 indicates that its risen to a level of interest that might result in a language change. I, for one, will be happy when I no longer have to instantiate an object just so I can call my non-static getter method to access a static variable in a subclass instance ...

一个接口永远不能被静态地解引用,例如issomething .member。接口总是通过引用该接口子类实例的变量来解除引用。因此,如果没有其子类的实例,接口引用永远不可能知道它引用的是哪个子类。

Thus the closest approximation to a static method in an interface would be a non-static method that ignores "this", i.e. does not access any non-static members of the instance. At the low-level abstraction, every non-static method (after lookup in any vtable) is really just a function with class scope that takes "this" as an implicit formal parameter. See Scala's singleton object and interoperability with Java as evidence of that concept. And thus every static method is a function with class scope that does not take a "this" parameter. Thus normally a static method can be called statically, but as previously stated, an interface has no implementation (is abstract).

Thus to get closest approximation to a static method in an interface, is to use a non-static method, then don't access any of the non-static instance members. There would be no possible performance benefit any other way, because there is no way to statically link (at compile-time) a ISomething.member(). The only benefit I see of a static method in an interface is that it would not input (i.e. ignore) an implicit "this" and thus disallow access to any of the non-static instance members. This would declare implicitly that the function that doesn't access "this", is immutate and not even readonly with respect to its containing class. But a declaration of "static" in an interface ISomething would also confuse people who tried to access it with ISomething.member() which would cause a compiler error. I suppose if the compiler error was sufficiently explanatory, it would be better than trying to educate people about using a non-static method to accomplish what they want (apparently mostly factory methods), as we are doing here (and has been repeated for 3 Q&A times on this site), so it is obviously an issue that is not intuitive for many people. I had to think about it for a while to get the correct understanding.

在接口中获取可变静态字段的方法是在接口中使用非静态getter和setter方法,来访问子类中的静态字段。旁注,显然不可变静态可以在带有静态final的Java接口中声明。