static修饰的成员变量是类级别共享数据,所有实例共用同一内存空间,存于方法区(jdk 8+为元空间),可通过类名直接访问,生命周期始于类加载终于类卸载。

在 Java 中,用 static 修饰成员变量,就能让这个变量成为“类级别”的共享数据——所有该类的实例对象共用同一份内存空间,修改任一对象的该变量,其他对象读取时也会看到变化。
static 成员变量属于类,不属于对象
普通成员变量(非 static)每个对象都有一份独立拷贝;而被 static 修饰的变量在类加载时就分配内存,只有一份,存放在方法区(JDK 8+ 是元空间),和具体对象无关。
- 即使没有创建任何对象,也能通过
类名.变量名直接访问(前提是权限允许) - 多个对象修改它,本质都是操作同一块内存
- 它的生命周期从类加载开始,到类卸载结束
声明和初始化方式
static 变量可以在声明时直接初始化,也可以在静态代码块中赋值。不能在构造方法或普通方法里用 static 声明(语法错误)。
- 直接初始化:
public static int count = 0; - 静态代码块初始化(适合复杂逻辑):
static {<br> count = initFromConfig();<br>} - 不推荐在构造方法中修改 static 变量来“模拟实例行为”,容易引发线程安全或逻辑混乱问题
典型使用场景
共享状态、全局计数、配置缓存、工具类常量等。
- 统计对象创建数量:
private static int instanceCount = 0;,在构造方法末尾instanceCount++ - 定义数学常量:
public static final double PI = 3.14159;(加 final 表示不可变) - 缓存数据库连接池或配置信息,避免重复加载
注意线程安全问题
多个线程同时读写同一个 static 变量时,可能产生竞态条件。如果需要线程安全:
- 用
volatile保证可见性(适用于简单读写,如标志位) - 用
synchronized或java.util.concurrent包下的原子类(如AtomicInteger)保障原子性 - 尽量设计为不可变(配合
final)或只读共享
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











