![Java王者归来:从入门迈向高手](https://wfqqreader-1252317822.image.myqcloud.com/cover/394/27563394/b_27563394.jpg)
8-7 变量的有效范围
在7-4-3节有讨论过参照计数减少的可能,其中一项是参照数据类型的变量已经离开了程序的有效范围,这一节将对此知识做一个完整的说明。
设计Java程序时,可以随时在使用前声明变量,可是每个变量并不是永远可以使用,通常将这个变量可以使用的区间称为变量的有效范围,这也是本节的主题。
8-7-1 for循环的索引变量
下面是一个常见的for循环设计。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P132_759153.jpg?sign=1739532074-16NeqzYWM3c9ZS7UpeCVhSYWPdoz4bKI-0-046fa086a73b8879304ad8ac3995d430)
对上述循环而言,作为索引的整数变量i的有效范围就是在这个循环,如果离开循环继续使用变量i就会产生错误。
程序实例ch8_12.java:这个程序第8行尝试在for循环外使用循环内声明的索引变量i,结果产生找不到符号的错误。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P132_759146.jpg?sign=1739532074-2FD2GRjfKdLPClBsRcCXgkwu6pFhNP8K-0-51e45aef8320b985a9aa00e7da213f51)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P132_565277.jpg?sign=1739532074-DsfcaElvck63ntg4eapF8OAs8ipsi1kI-0-486dbd338dcd1f2d6c8ef14c79531fbd)
8-7-2 foreach循环
foreach循环内所声明的变量,与for循环相同,只能在此循环范围内使用。
程序实例ch8_13.java:这个程序尝试在foreach循环外使用循环内声明的变量num,结果产生找不到符号的错误。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P132_759147.jpg?sign=1739532074-ZYXRC0tUG1moCzoBDvkRHNHCILE7bNZG-0-9dca6843a19c556843f4ef993ad43699)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P132_565287.jpg?sign=1739532074-wfh6FuKzYt62FuvZP6H8aoSElECtrbae-0-d2b34e88cc347149a3f6363858ebd036)
8-7-3 局部变量
其实在程序区块内声明的变量都算是局部变量,程序区块可能是一个方法内的语句,或者是大括号“{”和“}”间的区块,这时所设置的变量只限定在此区块内有效。
程序实例ch8_14.java:在区域外使用变量产生错误的实例,第6行设置的y变量只能在第5~8行间的区块使用,由于第9行输入y时,已经超出y的区域范围,所以产生错误。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P133_759160.jpg?sign=1739532074-UNUFzZPdZiJbFSV9DBgx2M8XOcvTdZ8u-0-7c726ef7e0637ae6a2407b1289fda672)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P133_759161.jpg?sign=1739532074-RYZnjdJFLPOzl5SQCUIKEJSEeeYiKnAF-0-b12e031837c0e363562b234141252c5e)
在设计Java程序时,外层区块声明的变量可以供内层区块使用。
程序实例ch8_15.java:外层区块声明的变量供内层区块使用的实例。程序第3行声明变量x,在内层区块第7行仍可使用。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P133_565743.jpg?sign=1739532074-gTgOFyEDlwbev5Do8tJyMCFwHSkc2t4a-0-7c2c03570dc0cb303a76ada35c72bb5c)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P133_565749.jpg?sign=1739532074-0KNjwqqeVD2F6Y6SC2aZQDp9f4hLxqza-0-f2fe8ececa1c1cf0bcb1149a362b58ff)
对上述程序而言,如果想在第5~9行区块结束后使用变量y,则必须重新声明,此时新声明的y变量与原先区块内的变量y,是不同的变量。
程序实例ch8_16.java:离开区块后,重新声明相同名称变量的应用。这个程序的第9行是重新声明变量y然后打印。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P133_565752.jpg?sign=1739532074-wfdDtFvb66RiLv2hI6lBRSXAN89G7RvK-0-a259fd60bdbf62c31840c496898a7712)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P133_565758.jpg?sign=1739532074-RJqfkZaftH4arG0HFjNUTDw1FWrm5hrh-0-0e846fd5c8dfe3b7eb2b3276ceb69217)
如果前面已经声明了变量,不可以在内圈重新声明相同的变量。其实可以解释为当一个变量仍在有效范围时,不可以声明相同名称的变量。
程序实例ch8_17.java:这个程序第6行重复声明第3行已经声明过的变量x,且此变量仍在有效范围内使用,所以产生错误。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P134_759166.jpg?sign=1739532074-Sz5mwZysEAWvtzSHFiWpxYIb8Zl8poNh-0-8d5db0d105ab046d76d791b9bdb16194)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P134_759167.jpg?sign=1739532074-DTEOFkWm3H9wYsPDs27fGsSiVjxdVyBq-0-82e95ae7812e51e6f2b21b150666080f)
8-7-4 类内成员变量与方法变量有相同的名称
在程序设计时,有时候会发生方法内的局部变量与类的属性变量(或是称成员变量)有相同的名称,这时候在方法内的变量有较高优先使用级,这种现象称为名称遮蔽(Shadowing of Name)。程序实例ch8_18.java:名称遮蔽的基本现象。这个程序的ShadowingTest类中有一个成员变量x,在方法printInfo()内也有局部变量x,依照名称遮蔽原则,所以第4行输出结果是main()方法A.printInfo(20)传来的20。如果想要输出目前对象的成员变量可以使用this关键词,这个关键词可以获得目前对象的成员变量的内容,它的使用方式如下。
this.成员变量
所以程序第5行会打印第2行成员变量设置的10。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P134_759170.jpg?sign=1739532074-5aG9Pk4yTdyTq2Xjt2Rkw4jQwSPCbheq-0-2b849109dc23e7a1c085dddb7c9e8ddf)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P134_566185.jpg?sign=1739532074-6GV7nPbRcjiejVmynr3s4MYVWcUj21ya-0-ee5e9c7f40256e952dcba8c243460b92)
下面以银行TaipeiBank类为例,再次说明名称遮蔽现象。
程序实例ch8_19.java:这个程序基本上是重新设计ch8_7.java,将程序第4行的saveMoney()的局部变量设为与成员变量balance名称相同,因为名称遮蔽现象,这时第5行的执行结果不会影响到成员变量balance。所以第20行执行输出所获得的结果仍是0。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P134_759172.jpg?sign=1739532074-NdvxKJFWTnSGdGBqWk7bzdf6oTAbur6p-0-ac4f4cf8db50c07e238fc477f697f747)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P135_566602.jpg?sign=1739532074-NeVOfv6b7NjmD9J8JKg8kc4CBeAbsbkc-0-f768df0ecad92d640d11b239823958dc)
程序实例ch8_20.java:重新设计ch8_19.java,在第5行修订增加this关键词,就可以将存款金额加总到成员变量balance内了。
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P135_566605.jpg?sign=1739532074-zcmpQEzE7e2MCbIpfinCcaEJKEsnyUly-0-fedd1766f38dbb09a752a9b268d73397)
执行结果
![](https://epubservercos.yuewen.com/9E44AA/15825993204148006/epubprivate/OEBPS/Images/Figure-P135_566611.jpg?sign=1739532074-xg5gpeX7T6LrCtqp133Ni8RYZ12EyV7Q-0-94749f87bd58fd6c81c612e65ebfa785)