Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java静态和最终静态变量初始化之间的差异_Java - Fatal编程技术网

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

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() {

输出:

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() {

        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能解决剩下的问题——鲍里斯的回答很好地涵盖了这一点。