
8-7 变量的有效范围
在7-4-3节有讨论过参照计数减少的可能,其中一项是参照数据类型的变量已经离开了程序的有效范围,这一节将对此知识做一个完整的说明。
设计Java程序时,可以随时在使用前声明变量,可是每个变量并不是永远可以使用,通常将这个变量可以使用的区间称为变量的有效范围,这也是本节的主题。
8-7-1 for循环的索引变量
下面是一个常见的for循环设计。

对上述循环而言,作为索引的整数变量i的有效范围就是在这个循环,如果离开循环继续使用变量i就会产生错误。
程序实例ch8_12.java:这个程序第8行尝试在for循环外使用循环内声明的索引变量i,结果产生找不到符号的错误。

执行结果

8-7-2 foreach循环
foreach循环内所声明的变量,与for循环相同,只能在此循环范围内使用。
程序实例ch8_13.java:这个程序尝试在foreach循环外使用循环内声明的变量num,结果产生找不到符号的错误。

执行结果

8-7-3 局部变量
其实在程序区块内声明的变量都算是局部变量,程序区块可能是一个方法内的语句,或者是大括号“{”和“}”间的区块,这时所设置的变量只限定在此区块内有效。
程序实例ch8_14.java:在区域外使用变量产生错误的实例,第6行设置的y变量只能在第5~8行间的区块使用,由于第9行输入y时,已经超出y的区域范围,所以产生错误。

执行结果

在设计Java程序时,外层区块声明的变量可以供内层区块使用。
程序实例ch8_15.java:外层区块声明的变量供内层区块使用的实例。程序第3行声明变量x,在内层区块第7行仍可使用。

执行结果

对上述程序而言,如果想在第5~9行区块结束后使用变量y,则必须重新声明,此时新声明的y变量与原先区块内的变量y,是不同的变量。
程序实例ch8_16.java:离开区块后,重新声明相同名称变量的应用。这个程序的第9行是重新声明变量y然后打印。

执行结果

如果前面已经声明了变量,不可以在内圈重新声明相同的变量。其实可以解释为当一个变量仍在有效范围时,不可以声明相同名称的变量。
程序实例ch8_17.java:这个程序第6行重复声明第3行已经声明过的变量x,且此变量仍在有效范围内使用,所以产生错误。

执行结果

8-7-4 类内成员变量与方法变量有相同的名称
在程序设计时,有时候会发生方法内的局部变量与类的属性变量(或是称成员变量)有相同的名称,这时候在方法内的变量有较高优先使用级,这种现象称为名称遮蔽(Shadowing of Name)。程序实例ch8_18.java:名称遮蔽的基本现象。这个程序的ShadowingTest类中有一个成员变量x,在方法printInfo()内也有局部变量x,依照名称遮蔽原则,所以第4行输出结果是main()方法A.printInfo(20)传来的20。如果想要输出目前对象的成员变量可以使用this关键词,这个关键词可以获得目前对象的成员变量的内容,它的使用方式如下。
this.成员变量
所以程序第5行会打印第2行成员变量设置的10。

执行结果

下面以银行TaipeiBank类为例,再次说明名称遮蔽现象。
程序实例ch8_19.java:这个程序基本上是重新设计ch8_7.java,将程序第4行的saveMoney()的局部变量设为与成员变量balance名称相同,因为名称遮蔽现象,这时第5行的执行结果不会影响到成员变量balance。所以第20行执行输出所获得的结果仍是0。

执行结果

程序实例ch8_20.java:重新设计ch8_19.java,在第5行修订增加this关键词,就可以将存款金额加总到成员变量balance内了。

执行结果
