为什么界面中的所有字段都是隐式静态和最终的?

时间:2009-10-03 11:27:39

标签: java interface static final language-implementation

我只是想了解为什么接口中定义的所有字段都隐含staticfinal。保留字段static的想法对我来说很有意义,因为你不能拥有接口的对象,但为什么它们是final(隐式)?

任何人都知道Java设计师为什么要在界面staticfinal中创建字段?

7 个答案:

答案 0 :(得分:120)

接口不能具有行为或状态,因为它仅用于指定交互合同,而不是实现细节。不允许方法/构造函数体或静态/实例初始化块强制执行任何行为。仅通过允许静态final字段来强制执行状态。因此,Class可以具有状态(静态),但实例状态不是由接口推断的。

BTW:Java中的常量由静态final字段定义(按照惯例,名称使用UPPER_CASE_AND_UNDERSCORES)。

答案 1 :(得分:25)

成为final

的原因

如果未将字段定义为final,则任何实现都可以更改字段的值。然后他们将成为实施的一部分。接口是纯规范,没有任何实现。

成为static

的原因

如果它们是静态的,那么它们属于接口,而不是对象,也不属于对象的运行时类型。

答案 2 :(得分:16)

这里隐藏了几点:

仅仅因为接口中的字段是隐式静态final并不意味着它们必须是编译时常量,甚至是不可变的。你可以定义例如。

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(请注意,在注释定义中执行此操作可以confuse javac,这与上面实际编译为静态初始化程序的事实有关。)

此外,这种限制的原因比技术更具风格,很多人会like to see it be relaxed

答案 3 :(得分:9)

字段必须是静态的,因为它们不能是抽象的(就像方法一样)。因为它们不能是抽象的,所以实现者将无法在逻辑上提供字段的不同实现。

我认为这些字段必须是最终字段,因为许多不同的实现者可以访问这些字段,这使得它们可以更改可能会出现问题(如同步)。还要避免重新实现(隐藏)。

只是我的想法。

答案 4 :(得分:2)

我认为这些字段必须是最终的,因为它们具有过度的限制性,而Java语言设计者则认为这是错误的。有时候,例如树处理时,需要在实现中设置对接口类型的对象执行操作所需的常量。选择实现类的代码路径是一个问题。我使用的解决方法是定义一个接口函数,并通过返回一个文字来实现它:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

然而,使用这种语法会更简单,更清晰,更不容易出现异常实现:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}

答案 5 :(得分:0)

规范,合同......现场访问的机器指令使用对象地址加字段​​偏移。由于类可以实现许多接口,因此无法使非最终接口字段在扩展此接口的所有类中具有相同的偏移量。因此,必须实现不同的字段访问机制:两个内存访问(获取字段偏移,获取字段值)而不是一个加上维护虚拟字段表(虚拟方法表的模拟)。猜猜他们并不想让jvm复杂化,可以通过现有的东西(方法)轻松模拟。

在scala中,我们可以在接口中有字段,但在内部它们是按照我上面的解释(作为方法)实现的。

答案 6 :(得分:-1)

<强> static

Java中static的任何内容(变量或方法)都可以Classname.variablenameClassname.methodname或直接调用。仅使用对象名称不必强制调用它。

在接口中,无法声明对象,static可以通过类名调用变量而无需对象名称。

<强> final

它有助于为变量保持一个常量值,因为它不能在其子类中被覆盖。