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

下面是例子:

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

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

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

IXMLizable.newInstanceFromXML(e);

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

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

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

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

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

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

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


当前回答

要解决这个问题: 错误:缺少方法主体,或声明摘要 static void main(String[] args);

interface I
{
    int x=20;
    void getValue();
    static void main(String[] args){};//Put curly braces 
}
class InterDemo implements I
{
    public void getValue()
    {
    System.out.println(x);
    }
    public static void main(String[] args)
    {
    InterDemo i=new InterDemo();
    i.getValue();   
    }

}

输出: 20.

现在我们可以在接口中使用静态方法

其他回答

不能在接口中定义静态方法,因为静态方法属于类而不是类的实例,而接口不是类。点击这里阅读更多。

然而,如果你愿意,你可以这样做:

public class A {
  public static void methodX() {
  }
}

public class B extends A {
  public static void methodX() {
  }
}

在这种情况下,你有两个类,两个不同的静态方法称为methodX()。

这个问题已经被问过了

重复我的回答:

在接口中声明静态方法从来没有意义。它们不能通过正常调用MyInterface.staticMethod()来执行。如果您通过指定实现类myimplemtor . staticmethod()来调用它们,那么您必须知道实际的类,因此接口是否包含它是无关紧要的。

更重要的是,静态方法永远不会被重写,如果你试图这样做:

MyInterface var = new MyImplementingClass();
var.staticMethod();

static的规则说必须执行在声明的var类型中定义的方法。因为这是一个接口,所以这是不可能的。

不能执行“result=MyInterface. staticmethod()”的原因是它必须执行MyInterface中定义的方法的版本。但MyInterface中不能定义一个版本,因为它是一个接口。它没有定义上的代码。

虽然你可以说这相当于“因为Java是这样做的”,但实际上,这个决定是其他设计决策的逻辑结果,也有很好的理由。

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

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

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

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

接口中静态方法的需求是什么,静态方法基本上是在你不需要创建对象实例时使用的,接口的整个思想是引入面向对象的概念,通过引入静态方法,你从概念中转移。

有几个答案讨论了可覆盖静态方法概念的问题。然而,有时你会遇到一种模式,它似乎正是你想要使用的。

例如,我使用对象关系层,该层有值对象,但也有用于操作值对象的命令。由于各种原因,每个值对象类都必须定义一些静态方法,以便框架找到命令实例。例如,要创建一个Person,你可以这样做:

cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();

通过ID加载Person

cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();

这是相当方便的,但它有它的问题;值得注意的是,静态方法的存在不能在接口中强制执行。接口中可覆盖的静态方法正是我们所需要的,只要它能以某种方式工作。

EJBs solve this problem by having a Home interface; each object knows how to find its Home and the Home contains the "static" methods. This way the "static" methods can be overridden as needed, and you don't clutter up the normal (it's called "Remote") interface with methods that don't apply to an instance of your bean. Just make the normal interface specify a "getHome()" method. Return an instance of the Home object (which could be a singleton, I suppose) and the caller can perform operations that affect all Person objects.