静态变量是类的“公共账本”,属于类本身而非实例,类加载时初始化一次且所有实例共享;可跨类通过public static访问;静态代码块在类首次加载时执行一次,用于一次性初始化;多线程修改需用AtomicInteger或synchronized保证线程安全。

静态变量是类的“公共账本”
static 修饰的变量属于类本身,不是某个对象。它在类加载进 JVM 时就分配内存,只初始化一次,所有实例读写的是同一块内存。比如统计对象个数:
class Counter {
static int count = 0;
Counter() { count++; }
}
每 new 一个 Counter,count 就加 1;三个实例后 Counter.count 的值就是 3。你不需要创建对象,也能直接用 Counter.count 获取当前总数。
跨类共享靠 public static 组合
想让多个类共用一个变量,只需把它声明为 public static,放在一个专门的类里(如 Config、SharedData):
public class SharedData {
public static String status = "INIT";
public static void updateStatus(String s) { status = s; }
}
其他类可随时访问或修改:
– ClassA 中执行 SharedData.status = "RUNNING"
– ClassB 中调用 System.out.println(SharedData.status) 就能拿到 "RUNNING"
注意:不同类加载器加载的同一个类,其 static 变量互不干扰,这是隔离边界。
静态代码块:类加载时的“初始化仪式”
static 代码块在类首次被加载时执行,且仅执行一次,常用于一次性初始化操作:
class DatabaseConfig {
public static String URL;
public static int MAX_CONN;
static {
URL = System.getProperty("db.url", "jdbc:h2:mem:test");
MAX_CONN = Integer.parseInt(System.getProperty("db.max", "10"));
System.out.println("Database config loaded.");
}
}
无论你 new 多少个 DatabaseConfig 实例,上面的代码块只运行一遍,且一定在任何静态变量使用前完成。它比构造方法更早,也比普通成员变量初始化更靠前。
线程安全不能靠直觉
多个线程同时改同一个 static 变量,容易出错。例如两个线程都执行 count++,可能只加了 1 次而不是 2 次。
推荐做法:
– 用 AtomicInteger 替代 int:
static AtomicInteger count = new AtomicInteger(0);
Counter() { count.incrementAndGet(); }
– 或加 synchronized 控制写操作:
public static synchronized void increment() { count++; }
– 避免在 static 方法中读-改-写复合操作,尽量封装成原子方法。

















