为什么界面变量默认为静态和最终?

Jot*_*thi 258 java interface

为什么Java中默认接口变量是静态的和最终的?

che*_*vim 255

来自Philip Shaw的Java界面设计常见问题解答:

接口变量是静态的,因为Java接口本身无法实例化; 必须在没有实例的静态上下文中分配变量的值.最终修饰符确保分配给接口变量的值是一个真正的常量,不能由程序代码重新赋值.

资源

  • 请注意,抽象类既不能"自己"实例化,也不能实例变量. (37认同)
  • 对`static`修饰符的这种解释是完全虚假的.类的公共实例变量是其接口的一部分,并且没有理由不在Java接口中抽象它们,就像实例方法一样.Java`接口`无法直接实例化并不重要 - 您仍然可以拥有实现`interface`的类实例,并且要求它们具有某个公共实例变量是明智的.至于关于`final`的部分,它根本没有提供解释 - 它只描述了`final`的含义. (16认同)
  • 接口不能有实例变量,以避免状态问题的多重继承.请参阅https://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html.由于相同的原因,类不能扩展多个类. (5认同)
  • 上面的引用在上下文中更好.它给出的原因是"接口变量旨在成为Java常量".引用只是详细说明为什么这样的常数将是静态的和最终的.这是真的,但真正的问题是:为什么不允许变量作为*实际接口*的一部分(即指定必须在实现类中出现的非私有成员的名称和类型).如果他们想要特殊的"接口常量",他们可以使用新的语法,或者只是决定接口中实际*定义*的任何变量都是接口常量. (3认同)

dga*_*002 38

由于接口没有直接对象,访问它们的唯一方法是使用类/接口,因此如果接口变量存在,它应该是静态的,否则它根本不可访问外部世界.既然它是静态的,它只能保存一个值,任何实现它的类都可以改变它,因此它会变得一团糟.

因此,如果有一个接口变量,它将是隐式静态的,最终的,显然是公共的!


Nut*_*tan 35

public:用于跨所有类的可访问性,就像界面中存在的方法一样

静态:如接口不能有一个对象,该interfaceName.variableName可用于引用它或者直接在VARIABLENAME在执行它的类.

final:使它们成为常数.如果2类实现相同的接口,你给他们两个来改变权值,将发生在VAR,这就是为什么只有一个初始化时间允许的电流值的冲突.

所有这些修饰符都是隐含的接口,你真的不需要指定它们中的任何一个.


Mal*_*von 12

(这不是一个哲学的答案,而是一个实际的答案).对static修饰语的要求是显而易见的,已被其他人回答.基本上,由于接口无法实例化,访问其字段的唯一方法是使它们成为类字段 - static.

的背后的原因interface字段自动成为final(常数)是为了防止不同的实现意外更改接口变量的值可无意中影响其它实施方式的行为.想象一下下面的场景,其中一个interface属性没有final被Java 明确地变成:

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,想想如果另一个实现的类Actionable改变了接口变量的状态会发生什么:

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这些类是由类加载器在单个JVM中加载的,那么当它被执行后(在同一个线程或其他情况下)调用时,其行为NuclearAction会受到另一个类的影响,在这种情况下可能是灾难性的(从语义上讲).CleanActionperformAction()CleanAction

由于我们不知道a的每个实现interface将如何使用这些变量,因此它们必须隐含final.


Ami*_*ani 9

因为其他任何东西都是实现的一部分,并且接口不能包含任何实现.

  • 表明它是一个常数.Java没有const关键字.static final是你如何声明常量. (7认同)
  • 从Java 8开始,它们可以包含一个实现,但是如果你不需要反向兼容性,强烈建议不要使用它.:) (4认同)

Aru*_*aaj 6

因为:

Static:因为我们不能拥有接口对象,所以我们应该避免使用对象级别成员变量,而应该使用类级别变量,即静态变量。

Final:这样我们就不应该有不明确的变量值(钻石问题 - 多重继承)。

根据文档接口是合同而不是实现。

参考:Abhishek Jain在 quora 上的回答


Rub*_*bee 5

static - 因为Interface不能有任何实例.最后 - 因为我们不需要改变它.

  • "我们不需要"=="我们不被允许",不要混淆意义. (14认同)

Asi*_*taq 5

public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}
Run Code Online (Sandbox Code Playgroud)

这是解决方案。

System.out.println(A.x); // done
Run Code Online (Sandbox Code Playgroud)

我认为这是接口变量是静态的原因之一。

不要在Interface内部声明变量。

  • 实际上,如果没有规范“ Ax”,它甚至都不会被编译”,因此在接口中使用变量(隐式为public static final)实际上是安全的。 (3认同)