块(block)作用域
块(即复合语句)是指由一对大括号括起来的若干条简单的 Java 语句。块确定了变量的作用域。一个块可以嵌套在另一个块中。
需要注意的是,不能在嵌套的两个块中声明同名的变量。比如,这样就有问题:
public static void main(String[] args) {int n;{int k;int n; // Error -- can't redefine n in inner block}}
条件语句
不用多说,自己看例子:
// 你的业绩 目标if (yourSales >= 2 * target) {performance = "Excellent";bonus = 1000; // 奖金} else if (yourSales >= 1.5 * target) {performance = "Fine";bonus = 500;} else if (yourSales >= target) {performance = "Satisfactory";bonus = 100;} else {System.out.println("You're fired");}
循环
while
while 是一开始先判断,如果为 false ,则 while 循环一次也不会执行。如:
import java.util.*;public class Retirement{public static void main(String[] args){// read inputsScanner in = new Scanner(System.in);System.out.print("How much money do you need to retire? ");double goal = in.nextDouble();// 退休金额System.out.print("How much money will you contribute every year? ");double payment = in.nextDouble(); // 每存多少钱到退休金System.out.print("Interest rate in %: ");double interestRate = in.nextDouble(); // 退休金每年的利润double balance = 0;int years = 0;// update account balance while goal isn't reachedwhile (balance < goal){// add this year's payment and interestbalance += payment;double interest = balance * interestRate / 100;balance += interest;years++;}System.out.println("You can retire in " + years + " years.");}}
do…while
与 while 不同,do…while 是先执行后判断。也就是说,它至少会执行一次。如上面的 whlie 计算退休金可以改为,先计算退休账户的余额,在询问是否退休:
import java.util.*;public class Retirement2{public static void main(String[] args){Scanner in = new Scanner(System.in);System.out.print("How much money will you contribute every year? ");double payment = in.nextDouble(); // 每年存多少钱到退休金System.out.print("Interest rate in %: ");double interestRate = in.nextDouble(); // 退休金利润double balance = 0;int year = 0;String input;// update account balance while user isn't ready to retiredo{// add this year's payment and interestbalance += payment;double interest = balance * interestRate / 100;balance += interest;year++;// print current balanceSystem.out.printf("After year %d, your balance is %,.2f%n", year, balance);// ask if ready to retire and get inputSystem.out.print("Ready to retire? (Y/N) ");input = in.next();}while (input.equals("N"));}}
for 循环
for 循环是支持迭代的通用结构。如果要写一个循环 10 次的循环,for 循环比 while 循环更直观。
for 语句的第 1 部分通常用于对计数器初始化;第 2 部分给出每次新一轮循环执行前要检测的循环条件;第 3 部分指示如何更新计数器。
需要注意每一部分要符合要求,但有时也会出现问题,比如检测两个浮点数是否相等:
for (double x = 0; x != 10; x != 0.1)
上述循环永远不会结束。由于舍入的误差,最终可能得不到精确值。例如,在上面的循环中,因为 0.1 无法精确地用二进制表示,所以,x 将从 9.99999999999998 跳到 10.09999999999998 。
关于作用域,如果在第 1 部分声明一个变量之后,这个变量的作用域就是整个 for 循环:
for (int i = 1; i <= 10; i++){...}// i no longer defined here
如果你现在循环体外使用循环计数器,那可以在 for 循环外声明:
int i;for (i = 1; i<= 10; i++) {...}// i is still defined here
根据上面块作用域讲的,如果在外部声明了变量,那在 for 循环里也就不能再声明了,即使是在第一部分:
int i;for(int i = 1; i<= 10; i++) { // Error -- can't redefine i...}
另一方面,可以在各自独立的不同 for 循环中定义同名变量:
for(int i = 1; i <= 10; i++) {...}for(int i = 5; i <= 15; i ++) { // OK to define another variable named i...}
switch
当处理多个选项时,switch 派上了用场。
int choice = in.nextInt();switch (choice){case 1:...break;case 2: // 这种情况允许通过 fallthroughcase 3:...break;case 4:...break;default:...break;}
switch 中需要注意的是,break 语句。如果在 case 分支语句的末尾没有 break 语句,那就会直接执行下一个 case 语句。如果你想要严格对待,可以在编译编码时,加上 -Xlint:fallthrough :
javac -Xlint:fallthrough Main.java
如果你确实想要这样写,可以在外围方法加一个标注 @SuppressWarnings("fallthrough") :
@SuppressWarnings("fallthrough")public static void checkSwitch(int choice) {int temp;switch (choice) {case 1:...break;case 2: // 问题出在这里,但我加了注解...case 3:...break;case 4:...break;default:...}}
case 标签可以是:
- 类型为 char, byte, short, int, long 的常量表达式
- 枚举产量
- 从 Java SE 7 开始,允许字符串字面量
终端控制流程语句
break, continue. 不必多说。不过,不同的是,在 Java 里,他们支持带标签的语句,用于跳出多重嵌套的循环语句。
break ``` int count = 0; read_data: for(int i=1; i<10; i++) { for(int j=1; j<10; j++){
} } System.out.println(count); // 5count++;if (i == 2 && j == 2)break read_data;
_continue_
int count = 0; read_data: for(int i=1; i<10; i++) { for(int j=1; j<10; j++){ count++; if (j == 2) continue read_data; } } System.out.println(count); // 18
```
