Java流程控制的陷阱——if语句和循环体的陷阱
来源:互联网 发布:js input框不可修改 编辑:程序博客网 时间:2024/05/28 04:55
3、if语句的陷阱
3、1 else隐含的条件
else字面意义是“否则”,隐含的条件是前面条件都不符合,也就是else有一个隐含的条件,else if的条件是if显示条件和else隐式条件的交集。
public class IfErrorTest {public static void main(String[] args) {int age = 45;if ( age > 20 ) {System.out.println("青年人");}else if ( age > 40 ) {System.out.println("中年人");}else if ( age > 60 ) {System.out.println("老年人");}}}输出结果为:
青年人
上面的程序是试图根据年龄来判断属于青年人、中年人还是老年人。从表面上来看,程序的运行过程为:年龄大于20岁是青年人,年龄大于40岁的是中年人,年龄大于60岁的是老年人。但是最终输出的却是青年人。造成这个问题的原因就是else后的隐含条件,else的隐含条件就是不满足else之前的条件。换句话来说,上面的代码实质上等于如下代码。
public class IfErrorTest {public static void main(String[] args) {int age = 45;if ( age > 20 ) {System.out.println("青年人");}else if ( age > 40 && !(age > 20)) {System.out.println("中年人");}else if ( age > 60 && !(age > 40) ) {System.out.println("老年人");}}}这样就比较容易看出为什么会发生上面的错误。对于判断中年人和老年人的情况是永远不会发生的,因此,程序也永远不可能打印出中年人和老年人。为了能够达到预期的效果,将程序修改为如下所示。
public class IfRightTest {public static void main(String[] args) {int age = 45;if ( age > 60 ) {System.out.println("老年人");}else if ( age > 40 ) {System.out.println("中年人");}else if ( age > 20 ) {System.out.println("青年人");}}}输出结果为:
中年人
上面程序的判断逻辑可以转换为如下三种情形。
- age大于60,判断为“老年人”。
- age大于40岁,且age小于等于60岁,判断为“中年人”。
- age大于20岁,且age小于等于40岁,判断为“青年人”。
3、2 空语句
public class BlankStatement {public static void main(String[] args) {int age = 45;if ( age > 60 ); {System.out.println("老年人");}else if ( age > 40 ) {System.out.println("中年人");}else if ( age > 20 ) {System.out.println("青年人");}}}从表面上来看,这个程序应该一切正常,程序先处理小范围条件,后处理大范围的条件,应该输出“青年人”,但是程序却报错:Syntax error on token "else", delete this token。原因是:if ( age > 60 );,在判断之后有一个分号,这个分号就是一个空语句。也就是说,这个分号就是if语句的条件执行体,if语句到这里就完全结束了。需要指出的是,如果if语句后没有花括号括起来的条件执行体,那么这个if语句仅仅控制到该语句后的第一个分号处,后面部分将不再受该if语句的控制。
4、循环体的陷阱
4、1 循环体花括号
Java对于if语句、while语句、for语句的处理策略完全一样:如果紧跟该语句的是花括号括起来的语句块,那么该if语句、while语句、for语句将控制花括号括起来的语句块;如果if语句、while语句、for语句之后没有紧跟花括号,那么if语句、while语句、for语句的作用范围到该语句之后的第一个分号结束。
public class WhileScopeTest {public static void main(String[] args) {int i = 0 ; while ( i < 10 ) System.out.println(i);i ++;}}上面程序编译正常,运行时一直输出0,并且是一个死循环。出现这个输出结果是因为程序省略了while循环的循环体花括号,那么受while循环控制的循环体只有一行代码System.out.println(i);。接下来的i++;并不在循环体之内,将导致循环计数器i一直保持0。
只有当循环体内只包含一条语句时才可以省略循环体的花括号,此时循环本身不会受到太大的影响。当循环体有多条语句时,不可省略循环体的花括号,否则循环体将变成只有紧跟循环条件的那条语句。
4、2 省略花括号的危险
class Cat {private static long instance = 0;public Cat() {System.out.println("执行无参数的构造器");instance++;}public static long getInstance() {return instance;}}public class CatTest {public static void main(String[] args) {for ( int i = 0 ; i < 10 ; i ++ ) Cat cat = new Cat();System.out.println(Cat.getInstance());}}上面程序试图通过for循环来创建10个Cat对象,然后通过getInstance()静态方法获取instance的值,由于循环体只有一条语句,因此省略了循环体的花括号,但是如果尝试编译该程序,编译器会报错:Syntax error, insert ";" to complete Statement。发生这种错误的原因:因为Java语言规定:for、while或do循环中的重复执行语句不能是一条单独的局部变量定义语句;如果程序要使用循环来重复定义局部变量,这条局部变量定义语句必须放在花括号内才有效。因此将程序改为如下所示。
class Cat {private static long instance = 0;public Cat() {System.out.println("执行无参数的构造器");instance++;}public static long getInstance() {return instance;}}public class CatTest {public static void main(String[] args) {for ( int i = 0 ; i < 10 ; i ++ ) {Cat cat = new Cat();}System.out.println(Cat.getInstance());}}
1 0
- Java流程控制的陷阱——if语句和循环体的陷阱
- Java流程控制的陷阱——switch语句和标签陷阱
- Java流程控制的陷阱——for循环和foreach循环的陷阱
- if语句的陷阱
- 流程控制的陷阱
- 流程控制陷阱(Switch语句,标签,if语句,for循环,foreach循环的循环计数器)
- 流程控制的那些陷阱
- 26、流程控制的陷阱
- Java表达式的陷阱——关于字符串的陷阱
- Java表达式的陷阱——表达式类型的陷阱
- Java表达式的陷阱——正则表达式的陷阱
- Java表达式的陷阱——多线程的陷阱
- Java表达式的陷阱——输入法、注释字符和转义字符的陷阱
- [Delphi] if 判斷式的陷阱
- 线程中if的陷阱
- java中,switch语句的陷阱
- java中,switch语句的陷阱
- 需求的陷阱--调研、确认和控制
- python kmp算法简单实现
- Android进程间通信(IPC)机制Binder简要介绍和学习计划
- C# 序列化帮助类
- 学习OpenCV---阈值化
- Linux清理cached缓存
- Java流程控制的陷阱——if语句和循环体的陷阱
- assert()函数用法总结
- MySQL学习笔记 4:自定义函数和MySQL存储过程
- SQLAlchemy批量插入性能比较
- windows环境布置bttracker服务器和下载分享
- Java web service 实例
- vue 开发过程的问题
- JDK1.8 JVM生产环境参数配置
- 在JSP里使用CKEditor和CKFinder