5.1 成员变量与局部变量概述
根据声明变量的位置,变量可分为成员变量与局部变量。
成员变量其实就是声明在类中的属性,除此之外的位置声明的变量都是局部变量,包括:方法参数、方法体,条件语句、循环语句等位置。
下面的代码片段中,我声明了若干变量,除了第2行的num1,其它都是局部变量:
public class Variable {
public int num1; // 成员变量,默认初始值是 0
public void method1() {
int num2; // 局部变量,没有默认初始值
int num3 = 10; // 局部变量,初始值为10
if (num3 > 0) {
int num4 = 0; // 局部变量,初始值为0
num4++;
for (int i = 0; i < 10; i++) { // 局部变量,初始值为 0
int num5 = 0; // 局部变量,初始值为0
num5 += i;
}
}
}
}
成员变量的特点:
- 有初始默认值
- 可被类中其他代码访问
局部变量的特点:
- 没有默认初始值,赋值之前不能访问
5.2 作用域
作用域(Scope)有时称为可见性(Visibility),是指变量能够被直接访问的代码范围。
变量的作用域取决于它是成员变量还是局部变量:
- 成员变量:类中的成员都可以访问,但是要注意static方法/代码块不能直接访问实例变量(属性)
- 局部变量:只能在其所在范围或其嵌套范围中访问
比如下面的代码片段:
public class Scope {
public int i = 0;
public void method1() {
i++;
System.out.println(i);
}
}
上面的代码中第2行声明的变量就是成员变量,它的作用于比较大,能被本类中的方法所访问,就在第5行,对i及象奴了自增,接着输出到控制台。
如果是局部变量,其作用域就要注意
public void method2() {
int i = 1; // i是局部变量
for (int j = 0; j < 5; j++) { // j是局部变量
System.out.println(i);
}
}
上面的代码中第2行声明的变量i就是局部变量,它的作用域是它所在的整个方法和其中更小的作用域,此处是for循环。所以在在for循环的循环体中可以直接使用变量 i。
在声明变量时,成员变量不能重复声明同名的变量,但可以声明与成员变量同名的局部变量,且不能与其同范围或嵌套范围的局部变量同名。另外局部变量前的修饰符有一些限制,比如:不能使用static关键字修饰,不能使用访问控制修饰符修饰。而成员变量则没有这些限制。
public class Variable {
public int num1;
public void method2() {
int num1 = 10;
num1++;
}
}
上面代码中方法中的局部变量 num1 与类的成员变量 num1 同名了,但这是允许的,那么在方法中使用时,优先使用方法内声明的局部变量。
但是下面的代码片段就不允许:
public void method3() {
int num1 = 10;
for (int i = 0; i < 10; i++) {
int num1 = 1; // 重复声明变量
}
}
在方法体内声明的变量是局部变量,看起来和for语句中声明的局部变量不相关,但是它们是嵌套的作用域,这在Java中是不允许的。
5.3 局部类型推断
Java 10引入了一个称之为类型推导/推断(Type Inference)的特性用于局部变量的声明
语法说明:
var 变量名 = 值;
需要注意的是,使用 var 很一些注意的点:
- var只能用于局部变量的声明(方法体和代码块中)
- var进行变量声明的同时进行初始化,不能初始化为null
- var变量的数据类型是编译时通过右边的值推导出来的,不能改变;编译之后即被替换为确定的数据类型
- var不能推导数组中元素的类型,也不能接收数组初始化表达式、
- var不能用于方法返回值类型的声明
- var不是关键字,是保留类型名,允许使用它作为变量或方法名
示例代码如下:
var i = 0;
var s = "Hello Laotan!";
var dog = new Dog();
var var = 10;
下面的写法会有语法错误:
var i;
var o = null;
var[] nums=new int[]{1,2,3};
var nums2={1,2,3};
var的使用建议
- 声明变量时类型名较长,使用 var 提高可读性,比如:
ClassWithLongName c = new ClassWithLongName();
var c = new ClassWithLongName();
上面第1行代码中的变量类型是ClassWithLongName类,它的名称较长,通过使用 var 可以改写为第2行的写法,可以看出代码更简单。
- 声明的变量较多,可以对齐变量名,比如要声明的多个变量,它们的数据类型不相同,比如:
int num = 1;
String name = "老谭";
String[] cities = new String[ ]{"成都", "北京"};
User user = new User( );
这样的写法导致的结果就是变量名没有对齐,可读性差一点,如果改为下面的形式就很整齐:
var num = 1;
var name = "老谭";
var cities = new String[ ]{"成都", "北京"};
var user = new User( );
我个人认为这种新语法的使用取决于自己的偏好,如果觉得var声明的变量不够直观,完全可以使用常规的变量声明语法。
5.4 小结
本小节介绍了Java中成员变量与局部变量的区别,重点分析了它们的作用域及使用规则。成员变量声明在类中,具有默认初始值且作用域覆盖整个类;局部变量声明在方法或代码块中,无默认值且作用域受限。文章还讲解了Java 10引入的局部类型推断(var)特性,说明了其使用场景和限制条件,并提供了变量声明的优化建议。变量作用域规则和合理使用var可以提高代码可读性和整洁性。

被折叠的 条评论
为什么被折叠?



