简体   繁体   English

Java静态和最终静态变量初始化之间的区别

[英]Java difference between static and final static variable initialization

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);
    }

}

Output : 输出:

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

Why is this different behavior for VAR1 and VAR2 ? 为什么VAR1和VAR2的行为不同?

The static fields get initialized one by one in order of declaration. 静态字段按声明顺序一一初始化。 In your particular case you initialize StaticTest stObj first. 在您的特定情况下,您首先要初始化StaticTest stObj This gets executed before the initialization of the VAR1 . 这将在VAR1初始化之前执行。 Thus VAR1 bears its default value when printing. 因此, VAR1在打印时VAR1其默认值。

However VAR2 is compile-time constant, thus the compiler optimizes its initialization and it is initialized first. 但是VAR2是编译时常量,因此编译器会优化其初始化,然后首先对其进行初始化。 That way one of the variables is initialized by the time you call the constructor, the other -not. 这样,在调用构造函数时便会初始化一个变量,而另一个则不是。

VAR2 is a compile-time constant, so its value is "baked in" to every call site. VAR2是一个编译时常量,因此其值被“烘焙”到每个调用站点中。 It therefore doesn't matter that you use it before you would expect to see it initialized. 因此,在期望看到它已初始化之前使用它并不重要。 If you change it to something which isn't a constant as far as the compiler is concerned, eg 如果将其更改为就编译器而言不是常数的东西,例如

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

then you'll see the same behaviour as for VAR1 (in terms of the output). 那么您将看到与VAR1相同的行为(就输出而言)。

See section 15.28 of the JLS for more information about constant expressions. 有关常量表达式的更多信息,请参见JLS的15.28节

VAR1 can be changed, VAR2 can't. VAR1可以更改, VAR2不能更改。

Try this: 尝试这个:

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.
}

VAR2 cannot be changed one the class has been initialised, whereas any instance of the class can change VAR later on. 无法在已初始化类的情况下更改VAR2 ,而该类的任何实例以后都可以更改VAR

The issue here is that you're referring to the variable before it has been fully initialised. 这里的问题是,您要在变量完全初始化之前引用它。

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

You're creating an instance of the class when loading the class itself, before the other static members have been initialised. 在初始化其他静态成员之前,您在加载类本身时正在创建该类的实例。

Check the Java Language Specifications for more details (Chapter 12) . 有关更多详细信息,请查看Java语言规范(第12章)

(Generally, creating an instance of the class during its own construction will lead to problems: you should avoid this.) (通常,在自己的构造期间创建类的实例会导致问题:您应该避免这种情况。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM