38

为什么 java 常量声明为 static ?

class Foo{
    static final int FII = 2 ;
}

在此我了解final的使用?购买为什么它必须是静态的?为什么它应该是类变量,而不是实例变量?

4

4 回答 4

111

如果一个常量不是静态的,Java 将在类的每个对象中为该常量分配一个内存(即每个对象一个常量的副本)。

如果常量是静态的,则该类将只有一个常量副本(即每个类一个副本)。

因此,如果常量只有一个值,就应该声明为静态的。

如果每个对象的常量可能具有不同的值,例如对象的创建时间,则不应将其声明为静态。

于 2011-11-11T11:32:24.623 回答
42

如果它可能因类的实例而异,那么它显然不是一个常量。为每个实例获取不同的 pi 值意味着什么MathMath甚至不允许构造实例)?或者对每个String?

于 2011-11-11T11:22:30.680 回答
13

这只是为了让您无需该类的实例即可访问它们。

要求创建实例只是为了访问常量字段有点浪费资源。

于 2011-11-11T11:22:04.717 回答
2

为什么 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 外部使用。

于 2020-07-03T15:42:25.037 回答