为什么java常量声明为static?

时间:2011-11-11 11:21:06

标签: java static constants final class-variables

为什么java常量声明为static?

class Foo{
    static final int FII = 2 ;
}

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

4 个答案:

答案 0 :(得分:84)

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

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

因此,如果常量只有一个值,则应声明为static。

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

答案 1 :(得分:32)

如果它可能因类的实例而异,那么它显然不是常量。为Math的每个实例获取不同的pi值意味着什么(不是Math甚至允许构造实例)?或者为String的每个实例添加不同的不区分大小写的排序?

答案 2 :(得分:12)

只是这样你就可以在没有该类实例的情况下访问它们。

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

答案 3 :(得分:1)

为什么将Java常量声明为静态?

从技术上说不是,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的所有有关 Constant Types 的东西,类和对象-因此Jon Skeet关于数学示例的答案缺少一部分,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外使用,而无需(明确地)实例化该类。 / p>