成员变量属于对象,每个实例独有一份;类变量属于类,所有实例共享一份。前者存堆内存、生命周期同对象,后者存方法区、生命周期同应用,且类变量用static修饰、推荐用类名调用。

Java里“成员变量”和“类变量”常被混淆,其实它们本质不同:成员变量属于对象,每个实例独有一份;类变量属于类本身,所有实例共享一份。关键区别不在名字,而在归属、生命周期和内存位置。
归属与作用范围不同
成员变量(也叫实例变量)定义在类中、方法外,不加 static 修饰。它属于某个具体对象,每个 new 出来的实例都拥有自己独立的副本。比如 Person p1 = new Person(); Person p2 = new Person();,p1.name 和 p2.name 互不影响。
类变量(即静态变量)用 static 修饰,属于类,不是某个对象。无论创建多少个对象,AppConfig.userCount 全局只有一个,所有对象读写的是同一块内存。
- 成员变量只能通过对象调用:p1.age
- 类变量既可用类名调用(推荐):AppConfig.userCount,也可用对象调用(不推荐,易误导)
生命周期差异明显
成员变量的生命周期绑定对象:对象一创建,它就诞生;对象被 GC 回收,它随之消失。中间只要还有引用指向该对象,变量就一直有效。
类变量的生命周期绑定类:类第一次被加载进 JVM(比如首次 new 对象、首次访问静态成员),它就初始化并驻留在方法区;直到程序退出、JVM 关闭,才释放。
- 成员变量存在时间 ≈ 对象存活时间
- 类变量存在时间 = 整个应用运行周期
内存位置与初始化方式不同
成员变量存于堆内存,是对象数据的一部分;类变量存于方法区(JDK 8+ 是元空间),是类元数据的一部分。
两者都有默认初始值(int→0,String→null 等),但类变量在类加载阶段就完成初始化,成员变量则在对象实例化时初始化。
- 局部变量必须显式赋值才能使用,否则编译报错;而成员变量和类变量无需手动初始化
- 类变量支持 static final 常量形式,常用于配置项或全局标识
典型使用场景对比
需要记录每个对象独立状态时用成员变量:比如银行账户的 balance、用户的 username。
需要跨对象共享或统计全局信息时用类变量:比如网站总用户数 totalUsers、数据库连接池单例、应用版本号 VERSION。
- 误把计数器声明为成员变量,会导致每个对象都从 0 开始计,失去统计意义
- 把用户昵称声明为 static,结果所有用户显示同一个名字——这是典型归属错误
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











