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

Java中带名称的静态初始化器是否合法?解析Core Java示例编译报错

按需初始化代码编译失败的原因及修复

我只认识static {...}格式的静态初始化器,但在Cay Horstmann的《Core Java》12.4.13节「按需初始化」里,出现了private static Holder {...}的写法,目的是利用JVM仅在类首次使用时执行一次静态初始化的特性,实现单例的按需初始化且保证只初始化一次。但给出的代码编译报错,具体代码和错误信息如下:

原错误代码

public class OnDemandData {
  // private constructor to ensure only one object is constructed
  private OnDemandData() {}
  public static OnDemandData getInstance() {
    return Holder.INSTANCE;
  }
  // only initialized on first use, i.e. in the first call to getInstance
  private static Holder {
    // VM guarantees that this happens at most once
    static final OnDemandData INSTANCE = new OnDemandData();
  }

}

编译报错信息

/OnDemandData.java:12: error: <identifier> expected
  private static Holder {
                       ^
/OnDemandData.java:14: error: illegal start of expression
    static final OnDemandData INSTANCE = new OnDemandData();
    ^
/OnDemandData.java:17: error: class, interface, enum, or record expected
}
^
3 errors

问题根源

这是书中的笔误,原代码混淆了静态初始化块和静态内部类的语法规则:

  • 第12行的private static Holder {缺少类定义的关键字class,JVM无法识别这是一个类,因此报<identifier> expected错误
  • 第14行在内部类的成员前多写了static——因为Holder本身是静态内部类,其成员默认属于类级别,不需要重复添加static修饰符,这属于语法错误
  • 最后一行多余的}是前面类定义不完整导致的语法错位

修正后的正确代码

public class OnDemandData {
    // 私有构造方法,禁止外部实例化
    private OnDemandData() {}

    public static OnDemandData getInstance() {
        return Holder.INSTANCE;
    }

    // 私有静态内部类,仅在首次访问时被JVM加载初始化
    private static class Holder {
        // JVM保证静态成员的初始化线程安全且仅执行一次
        static final OnDemandData INSTANCE = new OnDemandData();
    }
}

核心原理

这种写法是经典的按需初始化Holder模式:

  • 静态内部类Holder不会随外部类OnDemandData的加载而初始化,只有当调用getInstance()方法、访问Holder.INSTANCE时,Holder类才会被加载
  • JVM的类加载机制天然保证了静态成员初始化的线程安全性,不需要额外加锁就能实现线程安全的懒加载单例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:55:40