成员变量定义在类内方法外,属类或对象,存于堆内存,有默认值;局部变量定义在方法、代码块或参数中,仅限花括号内有效,存于栈内存,必须显式初始化。

看定义位置就能立刻分清:写在类里、所有方法外面的是成员变量;写在方法里、构造器里、if或for代码块里,或者作为方法参数的,就是局部变量。用错位置会直接编译失败,或引发隐蔽逻辑问题。
定义位置和作用域决定能不能用
成员变量属于类或对象,整个类内(包括所有方法、构造器、代码块)都能访问,受private/public等修饰符控制可见性。
局部变量只活在它被声明的那一对花括号{}里——方法一结束、代码块一退出,它就消失,别的地方根本“看不见”它。
- 同名时,局部变量会覆盖(遮蔽)同名成员变量,想访问成员变量得加
this. - 不能在方法外引用局部变量,也不能跨方法共享局部变量
- 循环里的
int i = 0、if块里的String msg,都是典型的局部变量
初始化规则是硬性红线
成员变量系统自动给默认值:int→0,boolean→false,引用类型→null,不赋值也能编译通过。
立即学习“Java免费学习笔记(深入)”;
局部变量必须显式初始化后才能使用,哪怕只是声明后马上打印也会报错:
-
int x; System.out.println(x);→ 编译失败 -
int x = 0; System.out.println(x);或int x; x = 5; System.out.println(x);→ 正确
内存和生命周期影响设计安全
成员变量(实例变量)存在堆内存,随对象创建而生、GC回收而亡;静态成员变量在方法区,随类加载而生。
局部变量存在栈内存,每次方法调用时压栈,返回时立刻弹出销毁。
- 栈上分配快、释放快,局部变量天然线程私有,无需同步
- 堆上的成员变量可能被多线程共享,需考虑
synchronized或volatile等机制 - 别把循环计数器
i声明成成员变量——会破坏封装,还可能在并发下出错
修饰符支持体现职责分工
成员变量可加public、private、static、final、volatile等几乎所有修饰符,适合存对象状态(如User.name)或全局配置(如static final API_URL)。
局部变量不能加任何访问修饰符(public/private等),也不能加static,只适合临时计算、参数接收、中间结果存储。
- 方法参数本质就是局部变量,比如
void save(String id)中的id -
final可用于局部变量(如Lambda中捕获),但不是修饰符语法的一部分,而是语义约束 - 避免把本该局部的数据提升为成员变量——既浪费内存,又增加状态管理复杂度


















