静态变量是类级别共享内存,类加载时在元空间分配且仅一份,所有实例共用同一地址;声明须在类体外,推荐private static+公共getter/setter;静态上下文不可用this或非静态成员;与实例变量相比,其内存分配更早、位置不同(元空间vs堆)、生命周期更长(类卸载才释放);多线程下需同步(synchronized/AtomicInteger)避免竞态。

类变量(静态变量)本质是类级别的共享内存
Java 中用 static 修饰的变量属于类本身,不是某个对象。它在类加载时就分配内存(位于元空间),整个 JVM 生命周期内只存在一份。所有该类的实例——无论创建多少个——读写操作都指向同一块内存地址。比如 Counter.count 被修改后,任意实例调用 getCount() 都会看到最新值,哪怕此时还没有创建任何实例,也能直接通过 Counter.count 访问。
声明方式与访问规则必须匹配生命周期
静态变量必须定义在类体中、方法外;可搭配 public、private 等修饰符。推荐写法是 private static + 公共的 static getter/setter,既保证封装性,又支持统一管控逻辑(如校验、日志)。注意:静态上下文中(如静态方法、静态代码块)不能直接使用 this,也不能访问非静态字段或方法——因为此时可能根本不存在任何实例,编译器会直接报错。
和实例变量的根本区别在于内存分配时机与位置
- 实例变量:每次
new一个对象,就在堆中新开辟独立空间,彼此完全隔离 - 静态变量:类首次被主动使用(如第一次
new、调用静态方法、访问静态字段)时触发类初始化,在元空间中仅分配一次 - 实例变量随对象回收而释放(由 GC 决定);静态变量直到类卸载才释放(通常伴随 JVM 退出)
多线程环境下共享意味着必须处理并发安全
多个线程同时读写同一个静态变量,极易引发竞态条件。例如两个线程几乎同时执行 count++,可能都读到旧值 5,各自加 1 后都写回 6,最终结果仍是 6 而非预期的 7。解决路径有:
- 用
synchronized同步关键代码段或方法 - 改用原子类(如
AtomicInteger)替代普通int - 避免“读-改-写”这类复合操作,优先设计为不可变或纯函数式更新


















