为什么java常量声明为静态?
为什么 Java 常量声明为static
?
class Foo {
static final int FII = 2 ;
}
在这个例子中我理解了final
的使用,但是为什么它必须是静态的呢?为什么它应该是类变量而不是实例变量?
Why are Java constants declared static
?
class Foo {
static final int FII = 2 ;
}
In this example I understand the use of final
, But why does it have to be static? Why should it be a class variable and not an instance variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果常量不是静态的,Java 将在类的每个对象中为该常量分配一块内存(即每个对象有一个常量副本)。
如果常量是静态的,则该类将只有一份常量副本(即每个类一个副本)。
因此,如果常量只有一个值,则应将其声明为静态。
如果常量对于每个对象可能具有不同的值,例如对象的创建时间,则不应将其声明为静态。
If a constant is not static, Java will allocate a memory for that constant in every object of the class (i.e., one copy of the constant per object).
If a constant is static, there will be only one copy of the constant for that class (i.e., one copy per class).
Therefore, if the constant has only one value, it should declared static.
If the constant might have different value for each object, for example the creation time of the object, it should not be declared static.
如果它可能因类的实例而异,那么它显然不是一个常量。对于每个
Math
实例获得不同的 pi 值意味着什么(并不是说Math
甚至允许构造实例)?或者为String
的每个实例提供不同的不区分大小写的排序?If it could vary by the instance of a class, then it's clearly not a constant. What would it mean to get a different value of pi for each instance of
Math
(not thatMath
even allows instances to be constructed)? Or a different case insensitive ordering for each instance ofString
?这只是为了让您无需该类的实例即可访问它们。
要求创建实例只是为了访问常量字段有点浪费资源。
It is simply so that you can access them without an instance of that class.
Requiring that an instance be created just to access constant fields is a bit of a waste of resources.
技术上并非如此,JLS 将常量定义为最终常量表达式(在 java 中称为编译时常量表达式,但没有正式地称为
编译时常量表达式
)。表示声明为 Final 的变量,该变量使用常量表达式初始化,表示没有静态 - https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4但是该规范没有解决有关 java 所涉及的常量类型、类和对象的任何问题 - 因此 Jon Skeet 关于数学示例的回答缺少一部分,Math 类被认为是常量,因为你无法通过以下方式实例化它将其构造函数设为私有。
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Math.java -
支持类型本身是常量您需要确保其状态也是恒定的,但仅限于其可变且会受到类型外部更改的成员的影响。
例如,文本 PI 是公开的,因此可以从类型外部获取它。因此,为了确保它不会从外部更改,它是最终的,并且也是静态的,因此它将成为 Class Class
实例,可以在 Math 之外公开使用,而无需(显式)实例化该类。
Technically they aren't, JLS defines constants as final constant expression (which are referred to but not formally in java as
compile time constant expression
). meaning a variable declared final which is initialized with a constant expression, meaning without static - https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4But the specification does not address anything regarding Constant Types which java is all about, Classes and Objects - so Jon Skeet answer regarding Math example is missing one part, Math class is considered constant because you cannot instantiate it by making its constructor private.
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Math.java -
To support the Type itself being constant you need to make sure its state is also constant, but only for its members who are mutable and are exposed to changes from outside the type.
For example the literal PI is made public so it's available from outside the type. So to make sure it wont be changed from the outside it is made final, and also static so it will be part of the Class Class<Math> instance and could be exposed for use outside Math without the class being (explicitly) instantiated.