Java静态和最终静态变量初始化之间的差异
输出: Var1:0 Var2:20 施工后VAR1:10 为什么VAR1和VAR2的行为不同?VAR1可以更改,VAR2不能 试试这个:Java静态和最终静态变量初始化之间的差异,java,Java,输出: Var1:0 Var2:20 施工后VAR1:10 为什么VAR1和VAR2的行为不同?VAR1可以更改,VAR2不能 试试这个: public class StaticTest { private static StaticTest stObj=new StaticTest(); private static int VAR1=10; private static final int VAR2=20; public StaticTest() {
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);
}
}
VAR2不能在类初始化后更改,而该类的任何实例都可以在以后更改VAR
这里的问题是,您在完全初始化变量之前引用它
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.
}
在初始化其他静态成员之前,您正在加载类本身时创建该类的实例
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是一个编译时常量,因此它的值会被嵌入到每个调用站点中。因此,在期望看到它初始化之前使用它并不重要。如果你把它改成编译器认为不是常数的东西,例如
private static StaticTest stObj=new StaticTest();
private static int VAR1=10;
private static final int VAR2=20;
然后,您将在输出方面看到与VAR1相同的行为
有关常量表达式的更多信息,请参阅。静态字段按声明顺序逐个初始化。 在您的特定情况下,首先初始化StaticTest stObj。这将在VAR1初始化之前执行。因此,VAR1在打印时具有其默认值
然而,VAR2是编译时常量,因此编译器优化其初始化,并首先初始化它。这样,一个变量在调用构造函数时被初始化,另一个-不是。VAR2是一个常量值,但VAR1是一个简单的静态变量。这意味着VAR1将在stObj初始化后初始化。这就是为什么VAR1在第一次调用时为0[default int init value],在第二次调用后为10。但是没有人更改任何变量?变量VAR在设置为10之前最初为0。所以你的意思是说在编译时VAR2被假定为常量?@Amingh:这不是假设的问题,而是遵循JLS的问题。变量是静态的和最终的,它是基元类型,初始化表达式是编译时常量表达式;请看@JonSkeet,你说得对,但我认为在这个关于初始化顺序的问题上还有更多的问题。@Bruno:我的答案是关于为什么VAR1和VAR2的行为不同。我希望OP能解决剩下的问题——鲍里斯的回答很好地涵盖了这一点。