Java 为什么接口中的所有字段都是隐式静态和最终的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1513520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are all fields in an interface implicitly static and final?
提问by peakit
I am just trying to understand why all fields defined in an Interface are implicitly static
and final
. The idea of keeping fields static
makes sense to me as you can't have objects of an interface but why they are final
(implicitly)?
我只是想了解为什么接口中定义的所有字段都是隐式static
和final
. 保留字段的想法static
对我来说很有意义,因为您不能拥有接口的对象,但为什么它们是final
(隐式)?
Any one knows why Java designers went with making the fields in an interface static
and final
?
任何人都知道为什么 Java 设计者要在接口中创建字段,static
并且final
?
采纳答案by Adriaan Koster
An interface can't have behavior or state because it is intended to specify only an interaction contract, no implementation details. 'No behavior' is enforced by not allowing method/constructor bodies or static/instance initializing blocks. 'No state' is enforced by only allowing static final fields. Therefore, the class can have a state (static state), but the instance state is not inferred by the interface.
接口不能有行为或状态,因为它仅用于指定交互契约,没有实现细节。通过不允许方法/构造函数体或静态/实例初始化块来强制执行“无行为”。通过只允许静态最终字段来强制执行“无状态”。因此,类可以有状态(静态),但实例状态不是由接口推断的。
BTW : A constant in Java is defined by a static final field (and by convention the name uses UPPER_CASE_AND_UNDERSCORES).
顺便说一句:Java 中的常量由静态 final 字段定义(按照惯例,名称使用 UPPER_CASE_AND_UNDERSCORES)。
回答by NawaMan
The fields must be static because they can't be abstract (like methods can). Because they can't be abstract, the implementers will not be able to logically provide the different implementation of the fields.
字段必须是静态的,因为它们不能是抽象的(就像方法一样)。因为它们不能是抽象的,所以实现者将无法在逻辑上提供字段的不同实现。
The fields must be final, I think, because the fields may be accessed by many different implementers allows they to be changeable might be problematic (as synchronization). Also to avoid it to be re-implemented (hidden).
我认为这些字段必须是最终的,因为这些字段可能会被许多不同的实现者访问,允许它们可变可能会出现问题(作为同步)。还要避免它被重新实现(隐藏)。
Just my thought.
只是我的想法。
回答by Jesse Glick
There are a couple of points glossed over here:
这里有几个要点:
Just because fields in an interface are implicitly static final does not mean they must be compile-time constants, or even immutable. You can define e.g.
仅仅因为接口中的字段是隐式静态 final 并不意味着它们必须是编译时常量,甚至是不可变的。您可以定义例如
interface I { String TOKEN = SomeOtherClass.heavyComputation(); JButton BAD_IDEA = new JButton("hello"); }
interface I { String TOKEN = SomeOtherClass.heavyComputation(); JButton BAD_IDEA = new JButton("hello"); }
(Beware that doing this inside an annotation definition can confuse javac, relating to the fact that the above actually compiles to a static initializer.)
(请注意,在注释定义中执行此操作可能会混淆 javac,这与上述实际上编译为静态初始值设定项的事实有关。)
Also, the reason for this restriction is more stylistic than technical, and a lot of people would like to see it be relaxed.
此外,这种限制的原因更多的是文体而不是技术,很多人希望看到它放松。
回答by Gurpreet singh sidhuu
Reason for being final
存在的理由 final
Any implementations can change value of fields if they are not defined as final. Then they would become a part of the implementation. An interface is a pure specification without any implementation.
如果字段未定义为 final,则任何实现都可以更改字段的值。然后他们将成为实施的一部分。接口是没有任何实现的纯规范。
Reason for being static
存在的理由 static
If they are static, then they belong to the interface, and not the object, nor the run-time type of the object.
如果它们是静态的,那么它们属于接口,而不是对象,也不属于对象的运行时类型。
回答by Carl Klapper
I consider the requirement that the fields be final as unduly restrictive and a mistake by the Java language designers. There are times, e.g. tree handling, when you need to set constants in the implementation which are required to perform operations on an object of the interface type. Selecting a code path on the implementing class is a kludge. The workaround which I use is to define an interface function and implement it by returning a literal:
我认为字段是 final 的要求是过度限制并且是 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";
}
...
}
However, it would be simpler, clearer and less prone to aberrant implementation to use this syntax:
但是,使用此语法会更简单、更清晰且不易出现异常实现:
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";
...
}
回答by Yaroslav
Specification, contracts... The machine instruction for field access uses object address plus field offset. Since classes can implement many interfaces, there is no way to make non-final interface field to have the same offset in all classes that extend this interface. Therefore different mechanism for field access must be implemented: two memory accesses (get field offset, get field value) instead of one plus maintaining kind of virtual field table (analog of virtual method table). Guess they just didn't want to complicate jvm for functionality that can be easily simulated via existing stuff (methods).
规范、合同... 用于字段访问的机器指令使用对象地址加上字段偏移量。由于类可以实现许多接口,因此无法使非最终接口字段在扩展此接口的所有类中具有相同的偏移量。因此必须实现不同的字段访问机制:两次内存访问(获取字段偏移量,获取字段值)而不是一次加维护一种虚拟字段表(类似于虚拟方法表)。猜猜他们只是不想让 jvm 复杂化,因为这些功能可以通过现有的东西(方法)轻松模拟。
In scala we can have fields in interfaces, though internally they are implemented as I explained above (as methods).
在 Scala 中,我们可以在接口中有字段,尽管在内部它们是按照我上面解释的(作为方法)实现的。
回答by Sabika
static
:
static
:
Anything (variable or method) that is static
in Java can be invoked as Classname.variablename
or Classname.methodname
or directly. It is not compulsory to invoke it only by using object name.
static
Java 中的任何(变量或方法)都可以作为Classname.variablename
或Classname.methodname
或直接调用。仅使用对象名称调用它不是强制性的。
In interface, objects cannot be declared and static
makes it possible to invoke variables just through class name without the need of object name.
在接口中,不能声明对象,并且static
可以只通过类名调用变量而无需对象名。
final
:
final
:
It helps to maintain a constant value for a variable as it can't be overridden in its subclasses.
它有助于保持变量的恒定值,因为它不能在其子类中被覆盖。