变量生命周期

时间:2022-09-24 14:41:15

首先补充2个专业单词:生命周期 lifetime  作用域 scope

关于变量生命周期问题,稍不留神就容易犯错。下面举几道练习题来巩固这个知识点,意在让自己做注意这个小问题。

1.   程序执行的结果是:

 1 public class Test{
 2     int x = 12; 
 3     public void method(int x){
 4         x +=x;
 5         System.out.println(x);
 6     }
 7     public static void main(String[] args){
 8       Test t = new Test();
 9       t.method(5);
10     }
11 }  
A. 5 B. 10 C. 12 D. 17

分析:t.method(5)调用method(int x)方法,传入参数是x = 5。int x = 12这个x成员变量的生命周期就是整个类的生命周期。不幸的是Java规定,当局部变量与成员变量重名时,在方法内的局部变量具有更高的优先级,此时外部变量不在方法内起作用(C/C++也是这么规定的)。因此方法中运算是这样的:

1 public void method(int x){  // 传入 x = 5
2    x +=x;           // x = x + x = 5 + 5 = 10
3    System.out.println(x);  // 输出 10
4 }

当method(int x)方法调用结束,这个方法的栈帧就从Java栈中退出了,此时局部变量x的生命周期也就到头了。实际上成员变量x并没有起到任何作用,只是声明了一下而已。

2. 下列程序编译或运行的结果是:

 1 public static void main(String[] args) {
 2   for(int i=0;i<=100;i++) {
 3     int num = 100;
 4   }           // 用完直接销毁
 5    for(int j=0;j<=100;j++) {
 6      int num = 200;
 7    }           // 用完直接销毁 
 8    int num = 300;   // 重新声明变量
 9    System.out.println(num); 
10 }
A.输出:100   B.输出:200   C.输出:300   D.编译出错

分析:变量的作用域就是"{}"内,当"{}"执行结束,变量的生命周期也就结束了。本题中,每次for循环都声明int num,当for循环结束后相应的num局部变量被销毁。最后又声明int num = 300,它的生命周期就是此时开始到main()方法结束。下面简单分析一下这段代码在内存中做了啥事。

首先public static void main(String[] args) 方法被加载到Java栈中(一个方法对于一个栈帧),这个main栈帧包括了局部变量(其余的操作数等不讨论)num。第一个for循环时num = 100和i被压入栈,for循环结束i和num退栈,生命周期结束,被销毁。第二个for循环同第一个效果。到第三个num时必须声明类型,否则报错,因为之前声明的num已经被销毁。int num = 300的生命周期到main方法结束为止,因此System.out.println(num)输出的是300。输出完毕后栈底的main栈帧退栈,此时num生命周期结束。

 3.  下列程序编译或运行的结果是:   

1 public static void main(String[] args) {
2   int num = 100;
3   for(int i=0;i<=100;i++) {
4     int num = 10;
5   }
6    System.out.println(num);
7 }
A.输出:10    B.输出:100   C.输出:201   D.编译出错

分析:这道题乍一看,貌似和上面那题考查知识点相同。其实不然,比较题1,发现橙色的那部分是多出来的。Java规定,相同变量名只能声明一次,即使声明的类型不同也只能声明一次,否则编译错误(不符合语法规范)。int num = 100生命周期直到main方法结束,而在for循环内又声明了一次num变量,因此出错。其实这两个num放的位置是不同的,for循环内的num不会覆盖原来的num,由于作用域不同,其实是同名的两个变量。用一个比喻来说明这点,比如一个学校有两个叫"赵四"的同学,一个是1年级1班的,一个是1年级2班的,这两个其实是两个个体,存在的班级不同,只不过是名字相同而已。

  

总结:

  1)在Java中,不严格区分变量的声明与定义。也就是说Java语言,变量的声明就是定义。这与C/C++存在区别,C语言在运行程序时对声明是不会给变量分配内存空间,只有定义变量时才会给变量分配内存空间。

  2)Java变量只能定义一次,所在的块为其作用域,也就是说变量的生命周期和块同步。