1.const
(常量)
定义和特性:
- 定义:
const
关键字用于定义编译时常量,即在编译时就必须确定其值,且值不可改变。const
字段的值在整个程序的生命周期内保持不变。 - 存储位置:常量通常存储在程序的元数据中,它们会直接内联到使用它们的代码中,因此在多个地方引用同一个常量时,编译器会将常量值直接插入到代码中,不会分配内存来存储这个常量。
- 初始化时机:
const
字段必须在声明时进行初始化,且只能使用编译时常量来初始化。这意味着它只能使用数值、字符串等基本类型来赋值,而不能使用运行时计算的值。 - 修饰范围:
const
字段隐式是static
的,它们属于类本身而不是实例,也就是说可以通过类名来访问常量。
使用场景:
const
适用于那些在整个程序运行期间始终不会改变的值,例如数学常量(如圆周率 PI
)、物理常量等。
主要特点:
- 编译时常量。
- 在声明时必须初始化。
- 隐式静态的,不需要显式声明为
static
。 - 值在编译时内联,无法在运行时动态改变。
2.readonly
(只读字段)
定义和特性:
- 定义:
readonly
关键字用于定义运行时常量,即它的值只能在声明时或构造函数中进行赋值,一旦赋值完成就不能再修改。 - 存储位置:
readonly
字段的值是在运行时存储的,并且只能被分配一次。如果是类级别的readonly
字段,它会与实例字段类似地存储在堆中(对于引用类型的对象),而static readonly
字段则存储在静态区域。 - 初始化时机:
readonly
字段可以在声明时进行初始化,或者在构造函数中进行初始化。这意味着你可以根据传入的参数或运行时条件来为它赋值。 - 修饰范围:如果将
readonly
与static
一起使用,字段将属于类本身,而不是实例。否则,readonly
字段属于对象的实例。
使用场景:
readonly
适用于那些值在构造函数中可以动态计算并且初始化后不再改变的情况,例如配置参数、设备信息等。
主要特点:
- 运行时常量。
- 可以在声明时或构造函数中赋值。
- 一旦赋值后不可修改,但在构造期间可以有灵活性。
- 可以与
static
结合使用。
3.static
(静态字段)
定义和特性:
- 定义:
static
关键字用于定义类级别的成员,这些成员属于类本身,而不是类的实例。无论创建多少个类的实例,所有实例共享同一个static
成员。 - 存储位置:静态字段存储在内存的静态区域,即在整个程序的生命周期内都占据固定的内存位置,直到程序退出时才会被回收。
- 初始化时机:
static
字段可以在声明时初始化,也可以在静态构造函数中初始化。静态构造函数会在类的静态成员首次被访问时或者类的实例首次被创建时调用一次。 - 访问方式:静态成员通过类名访问,而不是通过实例来访问。它们是所有实例共享的,因此它们的值对于所有实例是相同的。
使用场景:
static
适用于需要在类级别共享的数据或函数,例如全局配置、缓存、计数器、工具方法等。
主要特点:
- 类级别成员,属于类本身。
- 所有实例共享同一个
static
字段。 - 可以通过类名访问,不需要实例化对象。
- 可以与
readonly
结合使用,用于创建类级别的只读字段。
关键字 | 分配时机 | 初始化时机 | 访问方式 | 是否可变 |
---|---|---|---|---|
const | 编译时常量 | 编译时初始化 | 类级别 (隐式 static ) |
不可变 |
readonly | 运行时常量 | 运行时初始化(构造函数或声明时) | 对象级别 | 运行时不可变,构造时可变 |
static | 在类首次被访问时 | 在类首次被访问时 | 类级别 | 可变 |