You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

final修饰符是否存在定义缺陷?附Java递归静态代码谜题解析

Java静态递归初始化谜题解析

嘿,来看看这道有意思的Java静态初始化谜题,先猜猜下面这段代码运行后会输出啥?

public class RecursiveStatic {
    public static void main(String[] args) {
        System.out.println(scale(5));
    }
    private static final long X = scale(10);
    private static long scale(long value) {
        return X * value;
    }
}

答案:0

解析过程

是不是有点出乎意料?咱们一步步拆解背后的逻辑:

  • Java类加载时,静态成员的初始化有固定顺序:先在准备阶段给静态字段分配内存并设置默认值(long类型默认是0),之后才在初始化阶段执行赋值语句。
  • 当JVM处理private static final long X = scale(10);时,会调用scale(10)方法,但此时X还没完成赋值,只能用默认值0。
  • scale(10)方法返回0 * 10 = 0,于是X被正式初始化为0。
  • 后续main方法调用scale(5),此时X已经是0,所以返回0 * 5 = 0,最终输出0。

如果调整代码,把X的定义改成private static final long X = scale(10) + 3;,同时在scale方法里打印X,你会看到先输出X = 0,最终X的结果是3。这看似违背了final的不可变特性?其实不然——final的约束是初始化完成后不能修改,而初始化过程中字段会先持有默认值,直到赋值表达式执行完毕,这是Java类加载机制的正常行为,只是递归初始化的场景放大了这个细节而已。

内容的提问来源于stack exchange,提问作者Little Helper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:17:25