块(block)作用域

块(即复合语句)是指由一对大括号括起来的若干条简单的 Java 语句。块确定了变量的作用域。一个块可以嵌套在另一个块中。
需要注意的是,不能在嵌套的两个块中声明同名的变量。比如,这样就有问题:

  1. public static void main(String[] args) {
  2. int n;
  3. {
  4. int k;
  5. int n; // Error -- can't redefine n in inner block
  6. }
  7. }

条件语句

不用多说,自己看例子:

  1. // 你的业绩 目标
  2. if (yourSales >= 2 * target) {
  3. performance = "Excellent";
  4. bonus = 1000; // 奖金
  5. } else if (yourSales >= 1.5 * target) {
  6. performance = "Fine";
  7. bonus = 500;
  8. } else if (yourSales >= target) {
  9. performance = "Satisfactory";
  10. bonus = 100;
  11. } else {
  12. System.out.println("You're fired");
  13. }

循环

while

while 是一开始先判断,如果为 false ,则 while 循环一次也不会执行。如:

  1. import java.util.*;
  2. public class Retirement
  3. {
  4. public static void main(String[] args)
  5. {
  6. // read inputs
  7. Scanner in = new Scanner(System.in);
  8. System.out.print("How much money do you need to retire? ");
  9. double goal = in.nextDouble();// 退休金额
  10. System.out.print("How much money will you contribute every year? ");
  11. double payment = in.nextDouble(); // 每存多少钱到退休金
  12. System.out.print("Interest rate in %: ");
  13. double interestRate = in.nextDouble(); // 退休金每年的利润
  14. double balance = 0;
  15. int years = 0;
  16. // update account balance while goal isn't reached
  17. while (balance < goal)
  18. {
  19. // add this year's payment and interest
  20. balance += payment;
  21. double interest = balance * interestRate / 100;
  22. balance += interest;
  23. years++;
  24. }
  25. System.out.println("You can retire in " + years + " years.");
  26. }
  27. }

do…while

与 while 不同,do…while 是先执行后判断。也就是说,它至少会执行一次。如上面的 whlie 计算退休金可以改为,先计算退休账户的余额,在询问是否退休:

  1. import java.util.*;
  2. public class Retirement2
  3. {
  4. public static void main(String[] args)
  5. {
  6. Scanner in = new Scanner(System.in);
  7. System.out.print("How much money will you contribute every year? ");
  8. double payment = in.nextDouble(); // 每年存多少钱到退休金
  9. System.out.print("Interest rate in %: ");
  10. double interestRate = in.nextDouble(); // 退休金利润
  11. double balance = 0;
  12. int year = 0;
  13. String input;
  14. // update account balance while user isn't ready to retire
  15. do
  16. {
  17. // add this year's payment and interest
  18. balance += payment;
  19. double interest = balance * interestRate / 100;
  20. balance += interest;
  21. year++;
  22. // print current balance
  23. System.out.printf("After year %d, your balance is %,.2f%n", year, balance);
  24. // ask if ready to retire and get input
  25. System.out.print("Ready to retire? (Y/N) ");
  26. input = in.next();
  27. }
  28. while (input.equals("N"));
  29. }
  30. }

for 循环

for 循环是支持迭代的通用结构。如果要写一个循环 10 次的循环,for 循环比 while 循环更直观。
for 语句的第 1 部分通常用于对计数器初始化;第 2 部分给出每次新一轮循环执行前要检测的循环条件;第 3 部分指示如何更新计数器。
需要注意每一部分要符合要求,但有时也会出现问题,比如检测两个浮点数是否相等:

  1. for (double x = 0; x != 10; x != 0.1)

上述循环永远不会结束。由于舍入的误差,最终可能得不到精确值。例如,在上面的循环中,因为 0.1 无法精确地用二进制表示,所以,x 将从 9.99999999999998 跳到 10.09999999999998 。
关于作用域,如果在第 1 部分声明一个变量之后,这个变量的作用域就是整个 for 循环:

  1. for (int i = 1; i <= 10; i++){
  2. ...
  3. }
  4. // i no longer defined here

如果你现在循环体外使用循环计数器,那可以在 for 循环外声明:

  1. int i;
  2. for (i = 1; i<= 10; i++) {
  3. ...
  4. }
  5. // i is still defined here

根据上面块作用域讲的,如果在外部声明了变量,那在 for 循环里也就不能再声明了,即使是在第一部分:

  1. int i;
  2. for(int i = 1; i<= 10; i++) { // Error -- can't redefine i
  3. ...
  4. }

另一方面,可以在各自独立的不同 for 循环中定义同名变量:

  1. for(int i = 1; i <= 10; i++) {
  2. ...
  3. }
  4. for(int i = 5; i <= 15; i ++) { // OK to define another variable named i
  5. ...
  6. }

switch

当处理多个选项时,switch 派上了用场。

  1. int choice = in.nextInt();
  2. switch (choice){
  3. case 1:
  4. ...
  5. break;
  6. case 2: // 这种情况允许通过 fallthrough
  7. case 3:
  8. ...
  9. break;
  10. case 4:
  11. ...
  12. break;
  13. default:
  14. ...
  15. break;
  16. }

switch 中需要注意的是,break 语句。如果在 case 分支语句的末尾没有 break 语句,那就会直接执行下一个 case 语句。如果你想要严格对待,可以在编译编码时,加上 -Xlint:fallthrough

  1. javac -Xlint:fallthrough Main.java

如果你确实想要这样写,可以在外围方法加一个标注 @SuppressWarnings("fallthrough")

  1. @SuppressWarnings("fallthrough")
  2. public static void checkSwitch(int choice) {
  3. int temp;
  4. switch (choice) {
  5. case 1:
  6. ...
  7. break;
  8. case 2: // 问题出在这里,但我加了注解
  9. ...
  10. case 3:
  11. ...
  12. break;
  13. case 4:
  14. ...
  15. break;
  16. default:
  17. ...
  18. }
  19. }

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++){
    1. count++;
    2. if (i == 2 && j == 2)
    3. break read_data;
    } } System.out.println(count); // 5
  1. _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

```