一、什么是成员变量,什么是局部变量
1、成员变量
成员变量分为实例变量(如果没有static修饰)或 类变量(有static修饰),定义在类内部、方法外部的变量,属于类或对象的属性。
2、局部变量
定义在方法内部、方法参数列表、代码块(for、if)的变量,属于临时变量。
二、核心区别
2.1 作用域(生效范围)
- 成员变量:
- 实例变量:作用域是整个对象,只要对象不被销毁,在类的任意非静态方法中都能够直接访问(注意访问权限修饰符);
- 类变量:作用域是整个类,通过类名.变量名就可以在任何地方访问,甚至不需要创建对象。
- 局部变量:
- 作用域仅限定义它的代码块,比如方法内定义的变量只能在方法内使用,if 代码块内的变量出了 if 就会失效,超过作用域后变量就会被销毁,无法访问。
2.2 默认值(面试常考踩坑点)
- 成员变量:
不管是实例变量还是类变量,JVM 都会自动赋予默认值,不同数据类型的默认值如下:
- 整数类型(byte/short/int/long): 0
- 浮点类型(float/double): 0.0
- 布尔类型(boolean): false
- 引用类型(String、对象等): null
- 局部变量:
JVM 不会给局部变量赋默认值,必须手动初始化后才可以使用,否则会直接编译报错
2.3 内存位置(底层原理)
- 成员变量:
- 实例变量:存储在堆内存中
- 类变量:存储在方法区(JDK8后是元空间)中
- 局部变量:
- 存储在栈内存的方法栈帧中
2.4 生命周期(存在时长)
- 成员变量:
- 实例变量:生命周期和对象一致,对象被GC 回收的时候,实例变量才会被销毁;
- 类变量: 生命周期和类一致,从类加载到 JVM,直到类被卸载,类变量一直存在
- 局部变量:
- 生命周期和代码块/方法的执行周期一致,方法开始执行时创建,方法执行结束或代码块执行完毕后,立即被销毁,无法复用。
三、开发中常见的错误场景
场景 1:局部变量遮蔽成员变量 (变量遮蔽)
当局部变量和成员变量重名的时候,局部变量会"遮蔽"成员变量,此时如果想要访问成员变量,只需要使用this 关键字(实例变量)或类名(类变量)
场景 2:局部变量的作用域混淆
新手容易在嵌套代码块中误用局部变量,比如在for 循环内定义的变量,出了循环就无法访问。