Java静态初始化不同输出解析:两种count定义的差异
Java静态变量初始化顺序导致的输出差异解析
固定主类代码
public class DemoApplication { public static void main(String[] args) { System.out.println("count: "+A.count); System.out.println("count: "+A.count); var a1=new A(); var a2=new A(); System.out.println("count: "+A.count); } }
两种A类定义及对应输出
情况1:count无显式初始化
public class A { public static A inst = new A(); public static int count; public A() { A.inst.count++; } }
运行输出:
count: 1 count: 1 count: 3
情况2:count显式初始化为0
public class A { public static A inst = new A(); public static int count=0; public A() { A.inst.count++; } }
运行输出:
count: 0 count: 0 count: 2
差异原因解析
核心问题出在Java类静态成员的初始化顺序,以及显式赋值的覆盖作用:
Java类第一次被访问时,JVM会按代码书写的顺序依次初始化静态成员;同时所有静态变量在正式初始化前,都会被JVM赋予默认值(比如int类型默认是0)。
情况1的执行流程
- 当main方法第一次打印
A.count时,触发A类初始化:- 先处理第一个静态成员
inst = new A():创建A实例并调用构造方法,构造方法里执行A.inst.count++——此时count已被默认初始化为0,执行++后变成1,随后把新实例赋值给inst。 - 接着处理第二个静态成员
public static int count;:因为没有显式赋值,不会修改当前count的值,保持构造方法修改后的1。
- 先处理第一个静态成员
- 所以前两次打印
count都是1;创建a1、a2时,每次构造方法都会让count++,数值从1→2→3,最后打印3。
情况2的执行流程
- 同样,第一次访问
A.count触发A类初始化:- 先处理
inst = new A():调用构造方法后count从默认0变成1,随后inst被赋值为新实例。 - 接着处理第二个静态成员
public static int count=0;:这里的显式赋值会直接把count重新设置为0,覆盖之前构造方法修改的1。
- 先处理
- 所以前两次打印
count都是0;创建a1、a2时,构造方法让count从0→1→2,最后打印2。
简单来说:情况2中count的显式赋值在inst初始化之后,会覆盖构造方法修改的数值;而情况1没有这步显式赋值,所以保留了构造方法修改后的结果。
内容的提问来源于stack exchange,提问作者Robert Rowbax
相关产品推荐
相关产品推荐

