块(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 inputs
Scanner 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 reached
while (balance < goal)
{
// add this year's payment and interest
balance += 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 retire
do
{
// add this year's payment and interest
balance += payment;
double interest = balance * interestRate / 100;
balance += interest;
year++;
// print current balance
System.out.printf("After year %d, your balance is %,.2f%n", year, balance);
// ask if ready to retire and get input
System.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: // 这种情况允许通过 fallthrough
case 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
```