「Java流程控制」switch结构

249 阅读11分钟

知识点解析

1.switch结构的核心概念
switch语句是一种多分支选择结构,它根据表达式的值来选择执行不同的代码块。与if-else结构相比,switch更适合处理离散的、有限个值的比较。

2.switch结构的基本语法

switch (表达式) {
    case1:
        // 代码块1
        [break;]
    case2:
        // 代码块2
        [break;]
    ...
    [default:
        // 默认代码块]
}

3.switch结构的特点

  • 表达式类型:可以是byteshortcharintString(Java 7+)、枚举类型。
  • case值:必须是常量表达式,且不能重复。
  • break语句:用于跳出switch结构,防止"程序穿透"。
  • default语句:可选,用于处理所有未匹配的情况。

4. switch结构的执行流程

  1. 计算表达式的值
  2. 将表达式的值与每个case值进行比较
  3. 找到匹配的case后,执行对应的代码块
  4. 如果遇到break语句,则跳出整个switch结构
  5. 如果没有匹配的case,则执行default代码块(如果有)

5. switch结构的注意事项

  • case值必须是常量表达式(final变量或字面量)
  • case值不能重复
  • break语句是可选的,但通常需要
  • default语句是可选的,但建议保留

6.switch与if-else的区别

  • switch:适用于离散的、有限个值的比较,代码更清晰。
  • if-else:适用于范围判断或复杂条件判断。

案例解析

案例:基本switch结构

public class SwitchExample1 {
    public static void main(String[] args) {
        int day = 3;
        String dayName;
        
        switch (day) {
            case 1:
                dayName = "星期一";
                break;
            case 2:
                dayName = "星期二";
                break;
            case 3:
                dayName = "星期三";
                break;
            case 4:
                dayName = "星期四";
                break;
            case 5:
                dayName = "星期五";
                break;
            case 6:
                dayName = "星期六";
                break;
            case 7:
                dayName = "星期日";
                break;
            default:
                dayName = "无效的日期";
        }
        
        System.out.println("今天是:" + dayName);
    }
}

运行结果

今天是:星期三

代码解析

  • Java源文件保存为“SwitchExample1.java”。
  • 定义变量day并赋值为3。
  • 使用switch结构根据day的值输出对应的星期名称。
  • day为3时,匹配case 3,输出"星期三"。

案例:switch穿透

public class SwitchFallThrough {
    public static void main(String[] args) {
        int number = 2;
        String result;
        
        switch (number) {
            case 1:
            case 2:
            case 3:
                result = "小数字";
                break;
            case 4:
            case 5:
            case 6:
                result = "中数字";
                break;
            default:
                result = "大数字";
        }
        
        System.out.println("数字分类:" + result);
    }
}

运行结果

数字分类:小数字

代码解析

  • Java源文件保存为“SwitchFallThrough.java”。
  • 定义变量number并赋值为2。
  • 使用switch结构实现穿透(fall-through),多个case共享同一段代码。
  • number为2时,匹配case 2,由于没有break,继续执行case 3的代码,最终输出"小数字"。

案例:String类型的switch

import java.util.Scanner;

public class StringSwitchExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入颜色(red/green/blue):");
        String color = scanner.nextLine();
        
        switch (color) {
            case "red":
                System.out.println("红色代表热情");
                break;
            case "green":
                System.out.println("绿色代表生机");
                break;
            case "blue":
                System.out.println("蓝色代表宁静");
                break;
            default:
                System.out.println("未知颜色");
        }
    }
}

运行结果

请输入颜色(red/green/blue):red
红色代表热情

代码解析

  • Java源文件保存为“StringSwitchExample.java”。
  • 使用Scanner获取用户输入的颜色字符串。
  • 使用String类型的switch结构根据颜色输出对应的描述。
  • 当输入"green"时,输出"红色代表热情"。

案例:枚举类型的switch

enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

public class EnumSwitchExample {
    public static void main(String[] args) {
        Season currentSeason = Season.SUMMER;
        String description;
        
        switch (currentSeason) {
            case SPRING:
                description = "万物复苏";
                break;
            case SUMMER:
                description = "烈日炎炎";
                break;
            case AUTUMN:
                description = "硕果累累";
                break;
            case WINTER:
                description = "白雪皑皑";
                break;
            default:
                description = "未知季节";
        }
        
        System.out.println("当前季节:" + description);
    }
}

运行结果

当前季节:烈日炎炎

代码解析

  • Java源文件保存为“EnumSwitchExample.java”。
  • 使用枚举类型的switch结构根据季节输出对应的描述。
  • currentSeasonSUMMER时,输出"烈日炎炎"。

案例:基本switch结构(带break)

public class BasicSwitchExample {
    public static void main(String[] args) {
        int fruitId = 2;
        String fruitName;
        
        switch (fruitId) {
            case 1:
                fruitName = "苹果";
                break;
            case 2:
                fruitName = "香蕉";
                break;
            case 3:
                fruitName = "橙子";
                break;
            case 4:
                fruitName = "葡萄";
                break;
            default:
                fruitName = "未知水果";
        }
        
        System.out.println("水果ID " + fruitId + " 对应的是:" + fruitName);
    }
}

运行结果

水果ID 2 对应的是:香蕉

代码解析

  • Java源文件保存为“BasicSwitchExample.java”。
  • 当fruitId为2时,匹配case 2,执行对应的代码块
  • break语句确保执行完case 2后跳出switch结构
  • 如果fruitId不在1-4范围内,将执行default代码块

案例:switch穿透(无break)

public class FallThroughExample {
    public static void main(String[] args) {
        int grade = 85;
        String evaluation;
        
        switch (grade / 10) {
            case 10:
            case 9:
                evaluation = "优秀";
                break;
            case 8:
                evaluation = "良好";
                // 注意这里没有break
            case 7:
                evaluation = "中等";
                break;
            case 6:
                evaluation = "及格";
                break;
            default:
                evaluation = "不及格";
        }
        
        System.out.println("成绩评价:" + evaluation);
    }
}

运行结果

成绩评价:中等

代码解析

  • Java源文件保存为“FallThroughExample.java”。
  • grade/10结果为8,匹配case 8
  • 由于case 8后没有break,代码会继续执行case 7的代码块
  • 最终evaluation被赋值为"中等"
  • 这种穿透特性在某些场景下非常有用

案例:String类型的switch(Java 7+)

import java.util.Scanner;

public class StringSwitchExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入命令(start/stop/restart):");
        String command = scanner.nextLine();
        
        switch (command) {
            case "start":
                System.out.println("系统正在启动...");
                break;
            case "stop":
                System.out.println("系统正在关闭...");
                break;
            case "restart":
                System.out.println("系统正在重启...");
                break;
            default:
                System.out.println("无效命令!");
        }
    }
}

运行结果

请输入命令(start/stop/restart):stop
系统正在关闭...

代码解析

  • Java源文件保存为“StringSwitchExample.java”。
  • 演示了Java 7引入的String类型switch支持
  • 根据用户输入的命令字符串执行不同操作
  • 大小写敏感,"Restart"将匹配default

案例:枚举类型的switch

enum Direction {
    NORTH, SOUTH, EAST, WEST
}

public class EnumSwitchExample {
    public static void main(String[] args) {
        Direction dir = Direction.EAST;
        String description;
        
        switch (dir) {
            case NORTH:
                description = "北方";
                break;
            case SOUTH:
                description = "南方";
                break;
            case EAST:
                description = "东方";
                break;
            case WEST:
                description = "西方";
                break;
            default:
                description = "未知方向";
        }
        
        System.out.println("当前方向:" + description);
    }
}

运行结果

当前方向:东方

代码解析

  • Java源文件保存为“EnumSwitchExample.java”。
  • 演示了枚举类型在switch中的应用
  • 每个枚举常量对应一个case
  • 类型安全,避免了字符串比较可能的问题

案例:switch表达式(Java 14+)

public class SwitchExpressionExample {
    public static void main(String[] args) {
        int day = 4;
        String dayType = switch (day) {
            case 1, 2, 3, 4, 5 -> "工作日";
            case 6, 7 -> "周末";
            default -> "无效日期";
        };
        
        System.out.println(dayType);
    }
}

运行结果

工作日

代码解析

  • Java源文件保存为“SwitchExpressionExample.java”。
  • 演示了Java 14引入的switch表达式
  • 使用箭头符号(->)简化语法
  • 可以直接返回值
  • 支持多case合并(case 1, 2, 3...)

常见错误及解决方法

错误:缺少break语句导致穿透

public class MissingBreakError {
    public static void main(String[] args) {
        int value = 1;
        switch (value) {
            case 1:
                System.out.println("一");
            case 2:
                System.out.println("二");  // 会无条件执行
            default:
                System.out.println("其他");  // 会无条件执行
        }
    }
}

运行结果

一
二
其他

解决方法:在每个case后添加break语句,除非有意使用穿透特性 修正后的代码

int value = 1;
switch (value) {
    case 1:
        System.out.println("一");
        break;
    case 2:
        System.out.println("二");
        break;
    default:
        System.out.println("其他");
}

运行结果

错误:case值重复

int value = 5;
switch (value) {
    case 5:
        System.out.println("五");
    case 5:  // 重复的case值
        System.out.println("重复的五");  // 编译错误
}

运行结果

java: case 标签重复

解决方法:确保每个case值都是唯一的。

错误:switch表达式类型不匹配

double price = 10.5;
switch (price) {  // 编译错误,switch不支持double类型
    case 10.5:
        System.out.println("十块五");
}

错误信息

Incompatible types. Found: 'double', required: 'char|byte|short|int|CharSequence|...'

解决方法

  • switch表达式必须是以下类型之一:
    • char
    • byte
    • short
    • int
    • CharSequence(String)
    • 枚举类型
  • 对于浮点数,可以转换为int或使用if-else结构

错误:default语句位置不当

int num = 3;
switch (num) {
    default:
        System.out.println("默认");
    case 1:
        System.out.println("一");  // 会无条件执行
}

运行结果

默认
一

解决方法

  • default语句可以放在任何位置,但建议放在最后
  • 如果确实需要放在前面,确保逻辑正确

实操练习

练习:月份季节判断 编写代码根据月份(1-12)输出对应的季节:

  • 3-5月:春季
  • 6-8月:夏季
  • 9-11月:秋季
  • 12、1、2月:冬季

答案

public class MyClass {
    public static void main(String[] args) {
        int month = 7;
        String season;

        switch (month) {
            case 3:
            case 4:
            case 5:
                season = "春季";
                break;
            case 6:
            case 7:
            case 8:
                season = "夏季";
                break;
            case 9:
            case 10:
            case 11:
                season = "秋季";
                break;
            case 12:
            case 1:
            case 2:
                season = "冬季";
                break;
            default:
                season = "无效月份";
        }

        System.out.println("季节:" + season);
    }
}

运行结果

季节:夏季

说明:Java源文件保存为“MyClass.java”。

练习:成绩等级判断 编写代码根据成绩(A、B、C、D、F)输出对应的描述:

  • A:优秀
  • B:良好
  • C:中等
  • D:及格
  • F:不及格

答案

public class MyClass {
    public static void main(String[] args) {
        char grade = 'B';
        String description;

        switch (grade) {
            case 'A':
                description = "优秀";
                break;
            case 'B':
                description = "良好";
                break;
            case 'C':
                description = "中等";
                break;
            case 'D':
                description = "及格";
                break;
            case 'F':
                description = "不及格";
                break;
            default:
                description = "无效成绩";
        }

        System.out.println("成绩描述:" + description);
    }
}

运行结果

成绩描述:良好

说明:Java源文件保存为“MyClass.java”。

练习:编写代码实现一个简单的计算器,根据用户输入的操作符(+、-、*、/)执行相应的运算。

答案

import java.util.Scanner;
public class MyClass {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入第一个数字:");
        double num1 = scanner.nextDouble();
        System.out.print("请输入操作符(+、-、*、/):");
        char operator = scanner.next().charAt(0);
        System.out.print("请输入第二个数字:");
        double num2 = scanner.nextDouble();
        double result;

        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    System.out.println("错误:除数不能为零");
                    return;
                }
                break;
            default:
                System.out.println("错误:无效的操作符");
                return;
        }

        System.out.printf("结果:%.2f %c %.2f = %.2f%n", num1, operator, num2, result);
    }
}

运行结果

请输入第一个数字:10
请输入操作符(+、-、*、/):/
请输入第二个数字:3
结果:10.00 / 3.00 = 3.33

说明:Java源文件保存为“MyClass.java”。

练习:交通信号灯 编写代码根据交通信号灯的颜色(红、黄、绿)输出对应的行动建议:

  • 红灯:停止
  • 黄灯:准备
  • 绿灯:通行

答案

import java.util.Scanner;

public class TrafficLight {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入交通信号灯颜色(红/黄/绿):");
        String color = scanner.nextLine();
        String action;

        switch (color) {
            case "红":
            case "red":
                action = "停止";
                break;
            case "黄":
            case "yellow":
                action = "准备";
                break;
            case "绿":
            case "green":
                action = "通行";
                break;
            default:
                action = "未知信号灯";
        }

        System.out.println("行动建议:" + action);
    }
}

运行结果

请输入交通信号灯颜色(红/黄/绿):红
行动建议:停止

说明:Java源文件保存为“MyClass.java”。

练习:switch穿透实现多值统一处理

public class MyClass {
    public static void main(String[] args) {
        char grade = 'B';
        String evaluation;

        switch (grade) {
            case 'A':
            case 'B':
                evaluation = "优秀或良好";
                break;
            case 'C':
                evaluation = "中等";
                break;
            case 'D':
                evaluation = "及格";
                break;
            case 'F':
                evaluation = "不及格";
                break;
            default:
                evaluation = "无效成绩";
        }

        System.out.println("成绩评价:" + evaluation);
    }
}

运行示例

成绩评价:优秀或良好

解析

  • Java源文件保存为“MyClass.java”。
  • case 'A'和case 'B'共享同一段代码
  • 演示了如何利用穿透特性简化代码

练习:switch表达式处理复杂逻辑(Java 14+)

public class MyClass {
    public static void main(String[] args) {
        int score = 85;
        String result = switch (score / 10) {
            case 10, 9 -> "A";
            case 8 -> "B";
            case 7 -> "C";
            case 6 -> "D";
            default -> {
                if (score >= 0 && score < 60) {
                    yield "F";
                } else {
                    yield "无效分数";
                }
            }
        };

        System.out.println("成绩等级:" + result);
    }
}

运行结果

成绩等级:B

解析

  • Java源文件保存为“MyClass.java”。
  • 演示了Java 14的switch表达式
  • 使用yield关键字返回值
  • 结合if-else处理更复杂的逻辑

练习:switch处理月份天数

public class MyClass {
    public static void main(String[] args) {
        int month = 2;
        int year = 2024;
        int days;

        switch (month) {
            case 1: case 3: case 5: case 7: case 8: case 10: case 12:
                days = 31;
                break;
            case 4: case 6: case 9: case 11:
                days = 30;
                break;
            case 2:
                // 闰年判断
                if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
                    days = 29;
                } else {
                    days = 28;
                }
                break;
            default:
                days = -1;  // 无效月份
        }

        if (days == -1) {
            System.out.println("无效月份");
        } else {
            System.out.println(year + "年" + month + "月有" + days + "天");
        }
    }
}

运行结果

2024年2月有29天

解析

  • Java源文件保存为“MyClass.java”。
  • 结合switch和if-else处理复杂逻辑
  • 演示了case穿透和break的使用
  • 包含闰年判断逻辑

练习:简易购物车折扣系统 编写代码根据用户等级(普通、VIP、SVIP)和购物金额(<100, 100-500, 500-1000, >1000)计算最终价格。

答案

import java.util.Scanner;
public class MyClass {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入用户等级(普通/VIP/SVIP):");
        String level = scanner.nextLine();

        System.out.print("请输入购物金额:");
        double amount = scanner.nextDouble();

        double discountRate = 1.0;

        switch (level) {
            case "普通":
                discountRate = switch ((int)(amount / 100)) {
                    case 0 -> 1.0;
                    case 1, 2, 3, 4 -> 0.95;
                    case 5, 6, 7, 8, 9 -> 0.9;
                    default -> 0.85;
                };
                break;
            case "VIP":
                discountRate = switch ((int)(amount / 100)) {
                    case 0 -> 0.95;
                    case 1, 2, 3, 4 -> 0.9;
                    case 5, 6, 7, 8, 9 -> 0.85;
                    default -> 0.8;
                };
                break;
            case "SVIP":
                discountRate = switch ((int)(amount / 100)) {
                    case 0 -> 0.9;
                    case 1, 2, 3, 4 -> 0.85;
                    case 5, 6, 7, 8, 9 -> 0.8;
                    default -> 0.75;
                };
                break;
            default:
                System.out.println("无效用户等级");
                return;
        }

        double finalAmount = amount * discountRate;
        System.out.printf("原价:%.2f,折扣率:%.1f%%,最终价格:%.2f%n",
                amount, discountRate * 100, finalAmount);
    }
}

运行结果

请输入用户等级(普通/VIP/SVIP):SVIP
请输入购物金额:1000
原价:1000.00,折扣率:75.0%,最终价格:750.00

说明:Java源文件保存为“MyClass.java”。

知识总结

  1. switch结构:用于多分支选择,适用于离散的、有限个值的比较。
  2. 表达式类型:支持byteshortcharintString(Java 7+)、枚举类型。
  3. case值:必须是常量表达式,且不能重复。
  4. break语句:用于跳出switch结构,防止穿透。
  5. default语句:可选,用于处理所有未匹配的情况。
  6. 穿透(fall-through):多个case可以共享同一段代码,但需谨慎使用。