4.2 分支结构 4.2.1 if条件语句
4.2 分支结构
Java
提供了两种常见的分支控制结构:if
语句和switch
语句,其中
if
语句使用**布尔表达式或布尔值**作为分支条件来进行分支控制;switch
语句则用于对多个整型值进行匹配,从而实现分支控制。
4.2.1 if条件语句
if语句的三种形式
if
语句使用布尔表达式或布尔值作为分支条件来进行分支控制。if
语句有如下三种形式。
第一种形式:
1 | if(logic expression) |
第二种形式:
1 | if (logic expression){ |
第三种形式:
1 | if (logic expression){ |
在上面if
语句的三种形式中,放在if
之后括号里的只能是一个逻辑表达式,即这个表达式的返回值只能是true
或false
。第二种形式和第三种形式是相通的,如果第三种形式中else if
块不出现,就变成了第二种形式。
条件执行体
在上面的条件语句中,if(logic expression)
、else if(logic expression)
和else
后花括号括起来的多行代码被称为代码块,一个代码块通常被当成一个整体来执行(除非运行过程中遇到return
、break
、continue
等关键字,或者遇到了异常),因此这个代码块也被称为条件执行体。例如如下程序。
1 | int age = 30; |
条件执行体只有一条语句的话可省略花括号
如果if(logic expression)
、else if(logic expression)
和else
后的代码块只有一行语句时,则可以省略花括号,因为单行语句本身就是一个整体,无须用花括号来把它们定义成一个整体。下面代码完全可以正常执行:
1 | // 定义变量a ,并为其赋值 |
建议不要省略条件执行体的花括号
通常建议不要省略if
、else
、else if
后执行体的花括号,即使条件执行体只有一行代码,也保留花括号会有更好的可读性,而且保留花括号会减少发生错误的可能。例如如下代码,则不能正常执行:
1 | // 定义变量b ,并为其赋值 |
上面的
1 | System.out.println("b不大于4"); |
这行代码总会执行,因为这行代码不属于else
后的条件执行体,else
后的条件执行体就是b--;
这行代码。if
、else
、else if
后的条件执行体要么是一个花括号括起来的代码块,则这个代码块整体作为条件执行体;要么是以分号为结束符的一行语句,甚至可能是一个空语句(空语句是一个分号),那么就只是这条语句作为条件执行体。**如果省略了if
条件后条件执行体的花括号,那么if
条件只控制到紧跟该条件语句的第一个分号处**。
如果if
后有多条语句作为条件执行体,若省略了这个条件执行体的花括号,则会引起编译错误看下面代码
1 | // 定义变量c ,并为其赋值 |
在上面代码中,因为if
后的条件执行体省略了花括号,则系统只把c-;
行代码作为条件执行体当c-;
语句结束后,if
语句也就结束了。后面的:
1 | System.out.println("c大于4"); |
这行代码已经是一行普通代码了,不再属于条件执行体,从而导致**else
语句没有匹配的if语句**,从而引起编译错误。
优先把包含范围小的条件放在前面处理
对于if语句,还有一个很容易出现的逻辑错误,这个逻辑错误并不属于语法问题,但引起错误的可能性更大。看下面程序。
1 | public class IfErrorTest { |
表面上看起来,上面的程序没有任何问题:人的年龄大于20岁是青年人,年龄大于40岁是中年人,年龄大于60岁是老年人。但运行上面程序,发现打印结果是:青年人,而正确的情况是:45岁是中年人;
else的隐含条件是对前面条件取反
对于任何的if else
语句,表面上看起来else
后没有任何条件,或者else if
后只有一个条件,但这不是真相:
因为else
的含义是“否则”,所以else
本身就是一个条件!else
的隐含条件是对前面条件取反。因此,上面代码实际上可改写为如下形式。
1 | public class IfErrorTest2 { |
省略…
正确的写法如下:
1 | public class IfCorrectTest { |
如果每次都去计算if
条件和else
条件的交集也是一件非常烦琐的事情,为了避免出现上面的错误,在使用if...else
语句时有一条基本规则:总是优先把包含范围小的条件放在前面处理,例如:age>60
和age>20
两个条件,明显age>60
的范围更小,所以应该先处理age>60
的情况。
注意:使用if...else
语句时,一定要先处理包含范围更小的情况