成员变量属于对象,每个实例独有;类变量用static修饰,被所有对象共享。前者存堆内存、生命周期随对象,后者存方法区、随类加载而存在,且静态方法不可访问成员变量。

Java 中成员变量和类变量的核心区别,在于“谁拥有它”和“它属于谁”。成员变量属于每个对象自己,类变量属于整个类、被所有对象共享。理解这点,就抓住了本质。
作用范围与归属关系
成员变量(也叫实例变量)没有 static 修饰,定义在类中、方法外。每创建一个对象,JVM 就为其分配一份独立的内存空间。比如:
class Person { String name; int age; }
两个 Person 对象的 name 和 age 彼此隔离,改一个不影响另一个。
类变量用 static 修饰,同样定义在类中、方法外。它只有一份,加载类时就分配在方法区,所有对象共用同一块内存。比如:
class Counter { static int count = 0; }
无论创建多少个 Counter 实例,count 始终是同一个变量。
生命周期与内存位置
成员变量的生命周期绑定对象:对象 new 出来时诞生,垃圾回收时消失;存在堆内存中,是对象数据的一部分。
类变量的生命周期绑定类:类被 ClassLoader 加载时就初始化,直到程序结束或类卸载才释放;存在方法区(JDK 8+ 是元空间),不是堆里的对象数据。
- 成员变量默认有初值(如 int 是 0,引用是 null)
- 类变量同样有默认初值,且只初始化一次
- 局部变量不在此列——必须显式赋值才能使用
访问方式与调用限制
成员变量只能通过对象访问:
Person p = new Person(); p.name = "Alice";
类变量既可用类名,也可用对象访问:
Counter.count++; 或 new Counter().count++;
但推荐用 类名.变量名,语义更清晰,避免误以为是对象私有数据。
注意:静态方法中不能直接访问成员变量,也不能用 this;因为静态方法随类加载就存在,而对象可能还没创建。
立即学习“Java免费学习笔记(深入)”;
典型使用场景
选成员变量当它描述“个体特征”:
用户账号的 username、订单的 orderNo、学生的 studentId——每个实例都不同。
选类变量当它表达“全局状态”或“共享配置”:
数据库连接池大小、应用版本号、登录用户总数、工具类中的常量(如 public static final String API_URL)。
一个常见错误是把计数器写成成员变量:
int totalCount = 0; → 每个对象都从 0 开始,无法累计
改成 static int totalCount = 0; → 所有对象操作的是同一个计数器


















