静态变量实现跨对象数据共享,核心是让变量属于类而非实例,所有对象共享同一内存;典型应用为线程安全的全局计数器,推荐用private static AtomicInteger配合incrementAndGet(),避免public static裸露及内存泄漏风险。

用静态变量实现跨对象数据共享,核心是让变量属于类本身,而不是某个实例。所有对象操作的是同一块内存,改一处,处处可见。全局计数器是最典型、最直观的应用场景。
静态变量怎么声明才合理
必须写在类体内部、方法外部;加 static 修饰符;推荐搭配访问控制,避免裸露修改:
- 用 private static 声明变量,保证封装性
- 提供 public static 的 getter 和 setter(或专用方法),便于后期加校验、日志或同步
- 不建议直接用
public static int count—— 看似省事,但失去控制力,测试和并发时容易出问题
实战:线程安全的全局计数器
计数器看似简单,但 count++ 是“读-改-写”三步非原子操作。多线程下直接用普通静态变量会丢值。正确做法:
- 高并发首选 AtomicInteger:
private static AtomicInteger count = new AtomicInteger(0);,调用count.incrementAndGet()即可 - 低并发或逻辑复杂时,可用 synchronized 块保护关键段,例如在 setter 中加锁
- 构造器里调用计数方法即可自动累加,无需每个 new 后手动更新
跨类访问与共享的实际写法
静态变量天然支持跨类使用,只要类能被访问到,就能通过类名直接读写:
- 在
Counter类中定义private static AtomicInteger total = new AtomicInteger(0); - 其他类如
UserService或OrderProcessor直接调用Counter.total.incrementAndGet() - 不需要 import 特殊包,也不依赖 Spring 容器 —— 纯 Java 原生能力
- 注意:不同类加载器加载的同一个类,其静态变量互不相通(少见但需知)
容易踩坑的几个关键点
静态变量不是万能胶,用错地方反而埋雷:
- 别存对象状态:比如把用户 session、数据库连接、Activity 引用塞进静态变量,极易引发内存泄漏
-
测试要重置:JUnit 单元测试间可能复用类,静态值残留会导致用例失败;可在
@After或@BeforeEach中重置计数器 -
初始化顺序要留心:若静态变量依赖系统属性或配置文件,而这些在类加载时尚未就绪,会抛
ExceptionInInitializerError -
替代方案更合适时就别硬扛:需要注入、多租户隔离、上下文感知等,该上
ThreadLocal或 Spring Bean 就别死守 static










