☕ 第二章 Java编程基础

2.4 选择结构语句

📄 一句话概括

选择结构就是程序的分岔路口——2.3 的比较/逻辑运算符算出 true/false,这节拿它当"路标"指挥程序走哪条道。两个问法:if 家族挨个问,switch 对号入座。

前置知识:2.3 Java中的运算符(比较出 boolean、逻辑运算符连接多个条件)。


1. if 单分支:满足才做

int score = 95;
if (score >= 90) {
    System.out.println("优秀!");
}
System.out.println("程序结束");   // 这行在 {} 外,永远执行

读法:"如果 score 大于等于 90,就执行大括号里的"。

🚨 新手第一大坑:if 后面乱加分号
if (score >= 90);        // ← 这个分号是"空语句"!
{
    System.out.println("优秀!");  // 变成了普通代码块,永远执行
}

分号把 if 的"身体"提前结束了,{} 变成无关的普通代码块。if 和 { 之间不许有分号。这个 bug 编译器不报错、程序照样跑,只是结果不对——最阴的一种。

2. if…else 双分支:二选一

int score = 55;
if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

两条路必走一条,且只走一条。else 不需要条件——"前面全不成立"就是它的条件。

3. if…else if…else 多分支:挨个问

成绩等级是经典例子:

int score = 85;
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

执行规则(重要):从上往下挨个问,问到第一个 true 就执行对应块、后面全部跳过(包括后面的 else if);全 false 才走 else。所以成绩 85 的路径是:>=90? false → >=80? true → 打印"良好",结束。

⚠️ 阶梯的顺序就是逻辑

如果把 score >= 60 写在最前面,85 分的人第一个问题就命中"及格",永远到不了"优秀"。范围从大到小(或从小到大)排,别乱序——这是 else if 最隐蔽的坑。

4. 嵌套 if:路口里还有路口

int age = 20;
boolean hasTicket = true;
if (age >= 18) {
    if (hasTicket) {
        System.out.println("欢迎入场");
    } else {
        System.out.println("请先买票");
    }
} else {
    System.out.println("未成年人禁止入场");
}

读法:else 跟离它最近的 if 配对——先在"成年"这个路口里再分"有票/没票"。嵌套别超过三层,太深了先想想能不能用 && 合并条件(age >= 18 && hasTicket)。

5. switch…case:对号入座

条件是"等值匹配"(某个变量等于哪个值)时,switch 比 if 阶梯清爽:

int month = 8;
switch (month) {
    case 3:
    case 4:
    case 5:
        System.out.println("春天");
        break;
    case 6:
    case 7:
    case 8:
        System.out.println("夏天");
        break;
    case 9:
    case 10:
    case 11:
        System.out.println("秋天");
        break;
    case 12:
    case 1:
    case 2:
        System.out.println("冬天");
        break;
    default:
        System.out.println("月份非法");
}

三个角色:

🚨 新手第二大坑:忘写 break(穿透)
int x = 1;
switch (x) {
    case 1:
        System.out.println("一");
    case 2:                                  // ← 上面没 break,穿透进来!
        System.out.println("二");
        break;
    default:
        System.out.println("其他");
}
// 输出:一 和 二 两行

匹配 case 1 进门后,打印"一",没 break 就继续往下把"二"也打了。利用它:多个 case 共用一段代码时故意连着写(上面季节例子就是这么干的);提防它:该断的时候记得断。

JDK 14 起有箭头写法 case 3, 4, 5 -> 自带 break 效果,老教材教的冒号写法必须先懂——面试和祖传代码里全是它。

📝 switch 括号里能放什么

byte、short、int、char、String(JDK 7+)、枚举。不能放 long、float、double、boolean。考试常客:问"switch 能不能接收 double"——不能。

6. 附:三元运算符——if…else 的单行缩写

int a = 10, b = 20;
int max = a > b ? a : b;      // 条件 ? 真时的值 : 假时的值
System.out.println(max);      // 20

读法:"a 大于 b 吗?是取 a,不是取 b"。只适合"二选一取一个值",逻辑一复杂就老实用 if…else。

7. if 还是 switch?怎么选

场景 用谁
条件是范围(>= 60、< 0 \|\| > 100) if
条件是复合判断(&&、||) if
条件是等值枚举(菜单 1/2/3、季节、星期) switch
拿不准 if(万金油)

一句话:switch 是"点名",if 是"面试"——点名对号入座快,面试能问任何问题。

8. 动手:成绩等级程序

第 1 步:IDEA02 项目 → src 右键 → New → Java Class → 输入 Demo05。

第 2 步:psvm 生成主方法,抄入:

public class Demo05 {
    public static void main(String[] args) {
        int score = 85;
        if (score >= 90) {
            System.out.println("优秀");
        } else if (score >= 80) {
            System.out.println("良好");
        } else if (score >= 60) {
            System.out.println("及格");
        } else {
            System.out.println("不及格");
        }

        switch (score / 10) {
            case 10:
            case 9:
                System.out.println("switch 判定:优秀");
                break;
            case 8:
                System.out.println("switch 判定:良好");
                break;
            case 7:
            case 6:
                System.out.println("switch 判定:及格");
                break;
            default:
                System.out.println("switch 判定:不及格");
        }
    }
}

第 3 步:绿三角 ▶ 运行,预期输出两行:良好 + switch 判定:良好。

第 4 步(三个 30 秒实验,比代码本身值钱):

  1. 把 score 改成 95,看 if 和 switch 是不是都变"优秀"
  2. 删掉 case 8: 里的 break,改 score = 85 再跑——看穿透把"及格"也带出来了
  3. 把 score / 10 理解一下:整数除法砍小数,85/10=8,正好变成等值匹配(2.3 的伏笔第一次实战)

9. 常见误区小结

⚠️ 误区 1:`if (score = 90)` 想赋值再判断

不行。括号里必须 boolean,= 产生的是 int,直接编译报错。判断用 ==。

⚠️ 误区 2:`if (...)` 后面随手加分号

空语句吃掉 if 的身体,{} 变普通代码块永远执行。编译不报错,结果不对。

⚠️ 误区 3:else if 阶梯条件乱序

挨个问、命中即停——范围条件必须有序排列,否则大范围先拦截、小范围永远轮不到。

⚠️ 误区 4:以为 case 之间天然隔开

case 只是入口标签,出口靠 break。忘 break 就是穿透。

⚠️ 误区 5:想用 switch 接收 double 或 boolean

类型不收:long/float/double/boolean 都不行。等值匹配小数请走 if。


10. 自测题

❓ Q1:`int x = 5; if (x > 3); System.out.println("A");` 输出什么?

输出 A,且无论 x 是多少都输出。那个分号是空语句,把 if 的身体提前结束了;println 在 if 外面,永远执行。

❓ Q2:成绩 75,走 `>=90 → >=80 → >=60 → else` 阶梯,哪几个条件会被计算?

三个:>=90(false)→ >=80(false)→ >=60(true,命中"及格"后停止)。命中即停,后面的 else if 和 else 全跳过。

❓ Q3:case 1 到 case 5 各打印星期名但全忘了写 break,x = 3 时会输出什么?

从 case 3 进门,穿透执行 case 3、4、5 的代码——输出三、四、五三行,直到撞见 break 或结尾。忘 break 不是语法错误,是逻辑错误。

❓ Q4:`int max = a > b ? a : b;` 用 if…else 展开。
int max;
if (a > b) {
    max = a;
} else {
    max = b;
}

三元运算符本质是"带值的 if…else",if…else 是"做事的",三元是"选值的"。

❓ Q5:把"判断分数是否非法(小于 0 或大于 100 就提示)"写成一行 if。

if (score < 0 || score > 100) { System.out.println("分数非法"); }——范围判断 + 复合条件,这是 if 的主场,switch 做不了。


11. 下一步学什么


12. 相关笔记