静态变量生命周期严格绑定类:从类加载开始,到类卸载结束;内存分配在准备阶段(方法区/jdk8+元空间),初始化在初始化阶段且仅一次;不依赖对象,不随方法调用创建或销毁。

Java类变量(即静态变量)的生命周期,严格绑定在类本身上:它从类被JVM加载进内存那一刻开始存在,直到该类被彻底卸载才消失。这个过程不依赖于任何对象实例,也不随方法调用而创建或销毁。
类变量何时被分配内存?
在类加载的「准备阶段」(Preparation),JVM为所有静态变量在方法区(JDK 8+ 是元空间)分配内存,并赋予默认初始值(如 int → 0,引用类型 → null)。注意:此时不会执行程序员写的初始化语句(比如 static int x = 5; 中的 = 5),那要等到「初始化阶段」才发生。
- final static 常量是例外:它们在准备阶段就直接赋值目标值(如 final static String NAME = "abc"; 的 "abc" 会立即存入常量池并关联到变量)
- 数组类型的静态变量(如 static int[] arr = new int[10];)会在初始化阶段执行 new 操作,实际内存分配发生在堆上,但变量本身(arr 引用)仍在方法区
类变量何时被初始化?
类变量的显式初始化(即代码中写的初始值或静态代码块里的逻辑)发生在「初始化阶段」,且只执行一次。这个阶段由类的首次主动使用触发,例如:
- 访问该类的静态字段(非 final 的)或调用静态方法
- new 一个该类的实例
- 反射调用 Class.forName("xxx")
- 子类初始化时,父类先完成初始化
多个线程同时触发初始化时,JVM 会保证仅有一个线程执行,其余阻塞等待——这是通过 Class 对象内置锁实现的。
类变量何时被回收?
类变量本身不会被单独回收;它的生命周期依附于整个类。只有当满足全部三个条件时,类才可能被卸载,其静态变量也随之从内存中清除:
- 该类的所有实例都已被垃圾回收
- 加载该类的 ClassLoader 实例本身也被回收(比如 Web 应用重启时,自定义的 ClassLoader 被丢弃)
- 该类对应的 java.lang.Class 对象没有任何强引用(包括静态引用、栈帧局部变量、其他对象字段等)
注意:由 Bootstrap、Extension、AppClassLoader 加载的系统类和应用类,在 JVM 正常运行期间几乎不会被卸载——所以你写的 public static 的变量,基本就是“活到 JVM 结束”。
和实例变量、局部变量的关键区别
类变量的“静态性”决定了它与对象和方法解耦:
- 实例变量:每个对象一份,随 new 出生,随 GC 回收
- 局部变量:在栈帧里分配,方法调用开始时存在,方法返回即销毁
- 类变量:一份全局共享,归类所有,随类生,随类灭
写代码时若误把本该属于对象状态的数据声明为 static,就会导致多实例间意外共享、状态污染——这是常见的并发和内存泄漏隐患。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











