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

下面是例子:

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

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

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

IXMLizable.newInstanceFromXML(e);

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

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

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

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

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

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

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


当前回答

“是否有一个特殊的原因,静态方法不能被覆盖”。

让我把这个问题重新定义一下。

“在编译时解析的方法不能在运行时解析,是否有特殊原因?”

或者,更完整地说,如果我想在没有实例的情况下调用一个方法,但知道这个类,我怎么能根据我没有的实例来解析它呢?

其他回答

可以实现的是静态接口(而不是接口中的静态方法)。实现给定静态接口的所有类都应该实现相应的静态方法。你可以从任何Class clazz中获得静态接口SI

SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null

然后你可以调用si.method(params)。 这将很有用(例如对于工厂设计模式),因为您可以从编译时未知类获得(或检查)SI静态方法实现! 动态分派是必要的,您可以通过扩展类(当通过静态接口调用时)来重写类的静态方法(如果不是final方法)。 显然,这些方法只能访问它们类的静态变量。

静态方法不像实例方法那样是虚拟的,所以我猜想Java设计者决定不让它们出现在接口中。

但是您可以将包含静态方法的类放在接口中。你可以试试!

public interface Test {
    static class Inner {
        public static Object get() {
            return 0;
        }
    }
}

“是否有一个特殊的原因,静态方法不能被覆盖”。

让我把这个问题重新定义一下。

“在编译时解析的方法不能在运行时解析,是否有特殊原因?”

或者,更完整地说,如果我想在没有实例的情况下调用一个方法,但知道这个类,我怎么能根据我没有的实例来解析它呢?

接口关注的是多态性,它本质上是绑定到对象实例的,而不是类。因此,静态在接口上下文中没有意义。

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

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