为什么 java 常量声明为 static ?
class Foo{
static final int FII = 2 ;
}
在此我了解final的使用?购买为什么它必须是静态的?为什么它应该是类变量,而不是实例变量?
为什么 java 常量声明为 static ?
class Foo{
static final int FII = 2 ;
}
在此我了解final的使用?购买为什么它必须是静态的?为什么它应该是类变量,而不是实例变量?
如果一个常量不是静态的,Java 将在类的每个对象中为该常量分配一个内存(即每个对象一个常量的副本)。
如果常量是静态的,则该类将只有一个常量副本(即每个类一个副本)。
因此,如果常量只有一个值,就应该声明为静态的。
如果每个对象的常量可能具有不同的值,例如对象的创建时间,则不应将其声明为静态。
如果它可能因类的实例而异,那么它显然不是一个常量。为每个实例获取不同的 pi 值意味着什么Math
(Math
甚至不允许构造实例)?或者对每个String
?
这只是为了让您无需该类的实例即可访问它们。
要求创建实例只是为了访问常量字段有点浪费资源。
为什么 java 常量声明为 static ?
从技术上讲,它们不是,JLS 将常量定义为最终常量表达式(在 java 中被称为但不是正式的compile time constant expression
)。表示声明为 final 的变量,它使用常量表达式初始化,表示没有静态 - https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4
常量变量是原始类型或 String 类型的最终变量,使用常量表达式初始化。
但是该规范没有解决任何关于Java 的常量类型、类和对象的问题 - 所以 Jon Skeet 关于 Math 示例的答案缺少一部分,Math 类被认为是常量,因为您无法通过将其构造函数设为私有来实例化它。
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Math.java -
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
public static final double PI = 3.14159265358979323846;
}
要支持 Type 本身保持不变,您需要确保其状态也是不变的,但仅限于其可变成员并且暴露于来自类型外部的更改。
例如,文字 PI 是公开的,因此可以从类型外部使用。因此,为了确保它不会从外部更改,它是最终的,也是静态的,因此它将成为Class Class<Math>实例的一部分,并且可以在没有(显式)实例化类的情况下公开以在 Math 外部使用。