变量作用域
变量是有作用范围(Scope)的,也即作用域。一旦超出变量的作用域,就无法再使用这个变量。在程序中,变量一定会被定义在某一对大括号中,该大括号所包含的代码区便是这个变量的作用域。
按作用域范围划分,变量分为成员变量和局部变量。
(1)成员变量
在类体内定义的变量称为成员变量,它的作用域是整个类,也就是说在这个类中都可以访问到定义的这个成员变量。
【例】
public class Demo {
static int i = 47; // 定义一个成员变量,作用域是整个类Demo
public static void main(String[] args) {
System.out.println(i);
}
}
【结果】
(2)局部变量
在一个方法或方法内代码块中定义的变量称为局部变量,局部变量在方法或代码块被执行时创建,在方法或代码块结束时被销毁。局部变量在进行取值前必须被初始化,否则会编译错误。
Java存在块级作用域,在程序中任意大括号包装的代码中定义的变量,它的生命仅仅存在于程序运行该代码块时。
例如:for循环、while循环、方法或方法的参数列表里。在循环里声明的变量只要跳出循环,这个变量便不能再使用。同样,方法或方法的参数列表里定义的局部变量,当跳出方法体之外,该变量也不能使用了。
【示例】
public class LocalVar {
public static void main(String[] args) { // main方法参数列表定义的局部变量args
int sum = 0; // main方法体内定义的局部变量sum
for(int i = 1; i < 5; i++) // for循环体内定义的局部变量i
sum += i;
System.out.println(sum);
}
}
【结果】
【结果分析】
在范例中,就有3种定义局部变量的方式。在第3行,在静态方法main参数列表中定义的局部变量args,它的作用范围就是整个main方法体:以3行的左花括号“{”开始,以第8行的“} ”结束。
在第4行,在main方法体内,定义了局部变量sum。它的作用范围从当前行(4行)到以第8行的“}”为止。
在第5行,把局部变量i声明在for循环里,它的有效范围仅在for循环内(5~6行),只要一离开这个循环,变量i便无法使用。
相对而言,变量sum的有效作用范围从第4行开始,到第8行结束,for循环也属于变量sum的有效范围,因此sum在for循环内也是可用的。
【局部变量在块作用域的应用】
public class LocalVar {
static int x = 10;
public static void main(String[] args) {
int outer = 1;
{ // 直接用{}来定义块
int inner = 2;
System.out.println("inner = " + inner);
System.out.println("outer = " + outer);
}
int inner = 3;
System.out.println("inner = " + inner);
System.out.println("outer = " + outer);
System.out.println("In class lecer, x = " + x);
}
}
【结果】
注:块作用域除了用for等循环或方法体的左右大括号来界定外,还可以直接用大括号{}来定义“块”。
【变量块作用域的嵌套】
Java中作用范围是禁止嵌套的,而在C/C++中则是允许的。
在Java中,在方法内定义的变量,其作用范围(包括方法的参数)是从它定义的地方开始,到它所作用范围终结的位置处结束。
如在方法的开始处定义了一个变量i,那么直到该方法结束处,都不能再定义另一个同名变量i。再如,如果在一个for循环体中定义了变量i,那么在这个for循环内不能再有同名变量,但出了for循环之后,是可以再次定义的。这就是作用域不能嵌套的意思。
而在C/C++中,作用域可以嵌套,甚至无限制地嵌套下去,这里每对大括号之间就是一个独立的作用域,内嵌套的同名变量覆盖外迁套的同名变量。如下表所示。
Java中类与方法中变量作用域可以嵌套
在Java中,类与方法之间作用域是可以嵌套的,可以把整个类看做一个大的作用域,它定义的字段(或称数据成员)可被方法中的同名字段所屏蔽,其行为类似于上表左侧所示的C/C++的作用域嵌套。如下:
public class LocalVar {
static int x = 10;
public static void main(String[] args) {
int x = 20;
System.out.println(x); // 局部变量覆盖成员变量
}
}
【结果】