Table of contents
Chapter 5:Control Statements: Part 2
重点
自增的前缀增量和后缀增量在性能上的区别
在大多数情况下,前缀增量和后缀增量的方式都可用于语句中的变量加1,但是性能上面一般来说前缀增量是稍微优于后缀增量的。一般情况下我们假设编译器能够对代码进行优化以获得最佳的性能,所以可以选择你最习惯的使用方式。
货币精度问题
不要使用double或者float类型的变量来执行精确的货币运算。浮点数的不精确性会产生错误,导致不正确的货币值。java API有提供java.math.BigDecimal类用于任意精度浮点值的计算。
自测题错误记录
一般情况下,for语句用于计数器控制循环,while语句用于标记控制循环。
在switch语句中,default情况不是必须的。最后的一个case也不一定非要加上break.
为了switch语句中测试一个值的范围,可以在case标号的范围初值和终值之间加上连字符(-)。
连续列出情况,但是各case之间没有语句,则这些情况将执行同样的一组语句。
break的注意事项
关于break ,在这里要记住两点。
首先,一个循环中可以有一个以上的break 语句。但要小心,太多的break 语句会破坏你的代码结构。
其次,switch语句中的break仅仅影响该switch 语句,而不会影响其中的任何循环。
其三,在内部循环中的break语句仅仅终止了该循环,外部的循环不受影响。
break label的用法
break语句除了在switch语句和循环中使用之外,它还能作为goto语句来使用。
为什么不用goto?
Java 中实际上有goto的,但是作为保留字了,不给开发者使用,所以有了也等于没有。而且使用goto通常使程序难以理解和难于维护。它也阻止了某些编译器的优化。
goto的优点
有些地方goto语句对于构造流程控制是有用的而且是合法的。例如,从嵌套很深的循环中退出时,goto 语句就很有帮助。因此,Java 定义了break 语句的一种扩展形式来处理这种情况。通过使用这种形式的break,你可以终止一个或者几个代码块。这些代码块不必是一个循环或一个switch语句的一部分,它们可以是任何的块。而且,由于这种形式的break 语句带有标签,你可以明确指定执行从何处重新开始。你将看到,break带给你的是goto 的益处,并舍弃了goto 语句带来的麻烦。
语法介绍
break label怎么写?
标签break 语句的通用格式如下所示:
break label;
标签break 语句的一个最普遍的用法是退出循环嵌套。例如,下面的程序中,外层的循环只执行了一次:
// Using break to exit from nested loops
class BreakLoop4 {
public static void main(String args[]) {
outer:
for(int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
for(int j=0; j<100; j++) {
if(j == 10)
break outer; // exit both loops
System.out.print(j + " ");
}
System.out.println("This will not print");
}
System.out.println("Loops complete.");
}
}
该程序产生如下的输出:
Pass 0: 0 1 2 3 4 5 6 7 8 9 Loops complete.
可以看到,当内部循环退到外部循环时,两个循环都被终止了。此时break兼顾了goto的功能也有break本身的功能。
但是你不能使用break语句将控制传递到不包含break语句的代码块。例如:
class BreakErr {
public static void main(String args[]) {
one: //标签
for(int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
}
for(int j=0; j<100; j++) {
if(j == 10)
break one; // WRONG
System.out.print(j + " ");
}
}
}
}
因为标签为one的循环没有包围break 语句,所以不能将控制传递到该块。
标签(label)怎么写?
要指定一个代码块,在其开头加一个标签即可。
标签(label )的写法是
任何合法有效的Java标识符+一个冒号
一旦你给一个块加上标签后,你就可以使用这个标签作为break语句的对象了。
continue label的用法
基本上和break label的用法一样,兼顾了goto的功能也具备continue的功能。但是需要注意的是,当continue从内循环跳到外循环的时候,他会直接让内循环和外循环都continue一次。例如:
public class Label {
public static void main(String[] args) {
int temp = 0;
out: // label
for (int i = 0; i < 3; ++i) {
System.out.println("I am here");
for (int j = 0; j < 20; ++j) {
if(temp==0) {
System.out.println("j: " + j);
if (j == 1) {
temp = j;
continue out; // goto label "out"
}
}
}
}
System.out.println("temp = " + temp);
}
}
Results:
I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1
continue会直接跳过两层的循环,里面的for和外面的for都相当于给continue了一次。
如果不用continue,那么用什么语句来代替continue的功能?
//使用continue
int sum = 0;
for(int i=0;i<5;i++){
if(i == 3){
continue;//i=3时进行下一次循环
}
sum += i;
}
//不使用continue
int sum = 0;
for(int i=0;i<5;i++){
if(i != 3){
sum += i;
}
}
这两个循环是等效的