第3章 选择语句
3.1比较运算符
大于> :只支持左右两边操作数是数制类型。如果前面变量的值大于后面变量的值,则返回true
大于等于>= :只支持左右两边操作数是数制类型。如果前面变量的值大于等于后面变量的值,则返回true
小于<: 只支持左右两边操作数是数制类型。如果前面变量的值小于后面变量的值,则返回true
小于等于<=:只支持左右两边操作数是数制类型。如果前面变量的值小于等于后面变量的值,则返回true
等于==:如果进行比较的两个操作数都是数值类型的,即时他们的数据类型不相同,只要他们的值相等,也都将返回true。如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象才返回true。
不等于!=:如果进行比较的两个操作数都是数值类型,无论他们的数据类型是否相同只要它们的值不相等,也都将返回true。如果两个操作数都是引用类型,只有当两个引用变量的类型具有父子关系时才可以比较,只要两个引用指向的不是同一个对象就会返回true。
3.2逻辑运算符
单与& 不短路与,作用与与相同,但不会短路
双与&& 前后两个操作数必须都是true才返回true,否则返回false
或| 不短路或,作用与或相同,但不会短路
双或|| 只要两个操作数中有一个是true,就可以返回true,否则返回false
非! 只需要一个操作数,如果操作数是true,则返回false,如果操作数为false,则返回true
异或^ 当两个操作数不同时才返回true,如果两个操作数相同则返回false
3.3 if语句
if语句使用布尔表达式或布尔值来作为分支条件来进行分支控制
单if
if (logic expression)
{
statememnt...
}
if-else分支
if(logic expression)
{
statement...
}
else
{
statement...
}
多if-else嵌套
if(logic expression)
{
statement...
}
else if(logic expression)
{
statement...
}
...//可以有零个或多个else if语句
else// 最后的else语句也可以省略
{
statement...
}
3.4 switch语句
switch:switch语句由一个控制表达式和多个case标签组成,和if语句不同的是,switch语句后面的控制表达式的数据类型只能是byte、short、char、int四种整数类型,枚举类型和java.lang.String类型,不能是boolean类型
switch往往需要在标签后紧跟一个代码块,case标签作为这个代码块的标识。
switch (epression)
{
case condition;
{
statement(s);
break;
}
case condition2;
{
statement(s);
break;
}
...
case confditioN;
{
statement(s);
break;
}
default;
{
statement(s);
}
}
这种分支语句的执行是先对expression求值,然后依次匹配condition1、condition2、conditionN等值,遇到匹配的值即执行对应的执行体,如果所有case标签后的值都不与expression表达式的值相等,则执行default后的代码块。
和if语句不同的是,switch语句中各case标签后代码块的开始点和结束点非常清晰,因此完全可以省略case代码块后代码块的花括号。与if语句中的else类似,switch语句中的default标签看似没有条件,其实是有的,就是expression表达式的值不能与前面任何一个case标签后的值相等
不带case的switch
switch(day){
case1:
case2:
case3:
case4:
case5:System.out.println("Weekday");break;
case0;
case6:System.out.println("Weekend");
如上所示,不要忘记在需要的时候使用break语句。一旦匹配其中一个case,就从匹配的case处开始执行,查到遇到break语句或到达switch语句的结束。这种现象称为“落空行为”。
3.5条件表达式
布尔表达式
if(x>0)
y=1;
else
y=-1;
条件表达式是一种完全不同的风格,在语句中没有明确出现if
boolean-expression? expression1:expression2;(布尔表达式?表达式1:表达式2)
如果布尔值为true,则条件表达式的结果为表达式expression1;否则,结果为表达式为expression2.
3.6常见错误和陷阱
忘记必要的括号
在if行出现错误的分号:这个错误比较难发现,因为它既不是编译错误也不是运行错误,而是一个逻辑错误
多布尔值得冗余测试
a中的方法明显是多余的,比较好的方法是直接测试布尔变量,如图b所示,可以避免出现难以发现的错误。使用=操作符而不是==操作符去比较测试条件中的两项是否相等是一个常见错误,它会把true直接赋给变量导致永远输出true
悬空else出现的歧义
当选择语句中出现两个if而只有一个else时,有可能会出现悬空else歧义,在同一个块中,else总是匹配离它最近的if,这里注意else缩进一定要注意位置,确保匹配正确。
两个浮点数值的相等测试
浮点数具有有限的计算精度;涉及精度计算的计算可能引入取整错误。
double x=1.0-0.1-0.1-0.1-0.1-0.1;
System.out.println(x==0.5);
这里X并不是精确等于0.5,而是0.5000000000000001,可以通过测试两数的差值小于某个非常小的值,来比较它们是否接近,通常将epsilon设为10^-14 来比较两个double类型的值,例如下面代码
final double EPSTLON=1E-14;
double x=1.0-0.1-0.1-0.1-0.1-0.1;
if(Math.abs(x-0.5)<EPSTLON)
System.out.println(x+" is approximately 0.5");
将0.5000000000000001近似等于0.5,Math.abs(a)方法可以用于返回a的绝对值
简化布尔变量赋值:优化代码
避免不同情形中的重复代码:便于修改,使代码更加美观
3.7操作符的优先级和结合规则
优先级由高到低
var++和var–(后置操作符)
+、-、++var、–var(前置操作符)(一元加减)
type(类型转换)
!非
/ % *
-+ (二元加减)
< <= > >=
!= ==
^
&&
||
+= = -= *= /= %=赋值运算符