静态和最终静态变量初始化之间的Java差异

时间:2012-03-30 12:56:41

标签: java

public class StaticTest {

    private static StaticTest stObj=new StaticTest();
    private static int VAR1=10;
    private static final int VAR2=20;

    public StaticTest() {

        System.out.println("Var1 : "+VAR1);
        System.out.println("Var2 : "+VAR2);
    }

    public static void main(String[] args) {
        System.out.println("VAR1 after constrution : "+StaticTest.VAR1);
    }

}

输出:

Var1:0 Var2:20 构造后的VAR1:10

为什么VAR1和VAR2会有这种不同的行为?

4 个答案:

答案 0 :(得分:5)

静态字段按声明顺序逐个初始化。 在您的特定情况下,首先初始化StaticTest stObj。这在VAR1初始化之前执行。因此,VAR1在打印时会带有默认值。

但是VAR2是编译时常量,因此编译器会优化其初始化并首先进行初始化。这样,其中一个变量在您调用构造函数时初始化,另一个 - 不是。

答案 1 :(得分:3)

VAR2是一个编译时常量,因此它的值被“烘焙”到每个调用站点。因此,在期望看到它初始化之前,使用它并不重要。如果在编译器方面将其更改为不是的常量,例如。

private static final int VAR2 = "xyz".length();

然后你会看到与VAR1相同的行为(就输出而言)。

有关常量表达式的详细信息,请参阅section 15.28 of the JLS

答案 2 :(得分:0)

VAR1可以更改,VAR2不能。

试试这个:

private static int VAR1=10;
private static final int VAR2=20;

public static void main(String[] args) {
    VAR1 = 25;
    VAR2 = 35; // You'll find a compilation error here.
}

答案 3 :(得分:0)

一个类初始化后,

VAR2无法更改,而该类的任何实例可以在以后更改VAR

这里的问题是你在变量完全初始化之前引用该变量。

private static StaticTest stObj=new StaticTest();
private static int VAR1=10;
private static final int VAR2=20;

在初始化其他静态成员之前,您正在加载类本身时创建该类的实例。

检查Java Language Specifications for more details (Chapter 12)

(通常,在自己构建过程中创建类的实例会导致问题:你应该避免这种情况。)