Java中静态代码块的执行

3
我正在Java中运行以下代码:
1)第一段代码:
public class Basic {


    static int a=10;
    static
    {
        a=20;
    }   

    public static void main(String args[])
    {
    System.out.println("Value of Static variable : "+Basic.a);
    }
}

输出为:静态变量的值为:20
2)第二段代码:
public class Basic {
    static
    {
        a=20;
    }   

    static int a=10;

    public static void main(String args[])
    {
    System.out.println("Value of Static variable : "+Basic.a);
    }
}

输出为:

输出结果:静态变量的值为:10

问题:我不明白为什么第二段代码的输出结果与第一段代码不同,因为当 JVM 运行静态块时,它会在 main 方法之前运行。在第一段代码中,静态块将在 main 方法之前运行,然后重新分配变量 a 的值为 20。但是,在第二段代码中,我在块之前初始化了变量 'a',并且当程序运行时变量 'a' 应该具有值 20,但它的值是 10,为什么?


2
你真的一点头绪都没有吗?第一段和第二段代码有什么不同?你得出了什么结论? - JB Nizet
2个回答

1

最简单的理解方式是认为静态字段的初始化和静态初始化块的执行是相同对待的。这意味着Java会为该字段分配内存(仅创建该字段),然后按顺序运行静态初始化。如果在字段之前找到静态初始化块,则将首先运行它,而值初始化将覆盖它。

对于实例初始化字段和实例字段也适用同样的规则。

为了简化此过程,可以假设Java为每个字段初始化创建了一个静态初始化块,就像您编写的代码一样:

static int a; static{a = 10;}
static
{
    a=20;
} 

这是针对第二类的内容:
static
{
    a=20;
}   

static int a; static{a = 10;}

然后按顺序运行静态块。

如果我把 static int a; 移到最后,那么它的值应该是 0,因为原始类型 int 的默认值是 0,对吗? - Shubhendu Pramanik

1
Java运行时系统保证静态初始化块按照它们在源代码中出现的顺序被调用。请参阅相关教程
对于您的第二个代码示例,以下是运行时系统执行声明后面的初始化的方式。 a = 10 初始化本质上是一个静态块,在源代码中按照它出现的顺序执行,这是在a = 20赋值之后,因此打印的值是10而不是20。
  public class Basic {
    static int a;

    static
    {
        a = 20;
    }
    static
    {
        a = 10;
    }

将声明放在类的开头,然后是静态块、构造函数和其他方法,这是标准的良好实践。在声明之前混合静态块可能会导致混淆,就像这个例子所展示的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接