自学内容网 自学内容网

深入解析 Java 的 switch 语句

深入解析 Java 的 switch 语句

在 Java 编程中,switch 语句是一种常用的控制流语句,它能够根据变量的不同值执行不同的代码块。与 if-else 语句相比,switch 语句在处理多个条件判断时更加简洁和清晰,尤其适用于对一个变量的多个可能值进行判断的场景。本文将详细介绍 switch 语句的基本语法、使用示例、穿透特性、Java 12 和 Java 13 引入的 switch 表达式和 yield 关键字,并讨论常见问题及其解决方案。

一、switch 语句的基本语法

switch 语句的基本语法如下:

switch (expression) {
    case value1:
        // 语句
        break;
    case value2:
        // 语句
        break;
    // 你可以有任意数量的 case 语句
    default:
        // 语句
}
  • expression:必须是一个整型、枚举类型、字符型或字符串类型的表达式。
  • case:每个 case 标签后的值必须是常量表达式,且数据类型必须与 switch 表达式类型一致。
  • break:用于终止一个 case 分支,防止程序继续执行后面的 case 分支。如果没有 break,程序将继续执行下一个 case 分支的语句(称为“穿透”)。
  • default:可选的,用于处理所有未匹配任何 case 标签的情况。
二、switch 语句的使用示例
示例 1:整型 switch 语句
public class SwitchExample {
    public static void main(String[] args) {
        int day = 3;
        String dayName;
        
        switch (day) {
            case 1:
                dayName = "Monday";
                break;
            case 2:
                dayName = "Tuesday";
                break;
            case 3:
                dayName = "Wednesday";
                break;
            case 4:
                dayName = "Thursday";
                break;
            case 5:
                dayName = "Friday";
                break;
            case 6:
                dayName = "Saturday";
                break;
            case 7:
                dayName = "Sunday";
                break;
            default:
                dayName = "Invalid day";
                break;
        }
        
        System.out.println("The day is: " + dayName);
    }
}

在这个示例中,根据变量 day 的值,switch 语句选择对应的 case 分支执行,并输出对应的星期几。如果 day 的值不在 1 到 7 的范围内,将执行 default 分支。

示例 2:字符串 switch 语句
public class SwitchExample {
    public static void main(String[] args) {
        String fruit = "Apple";
        
        switch (fruit) {
            case "Apple":
                System.out.println("The fruit is an Apple.");
                break;
            case "Banana":
                System.out.println("The fruit is a Banana.");
                break;
            case "Orange":
                System.out.println("The fruit is an Orange.");
                break;
            default:
                System.out.println("Unknown fruit.");
                break;
        }
    }
}

在这个示例中,根据变量 fruit 的值,switch 语句选择对应的 case 分支执行,并输出对应的水果名称。如果 fruit 的值不是已定义的水果,将执行 default 分支。

三、switch 语句的穿透特性

switch 语句中,如果 case 分支中省略 break 语句,程序将继续执行后续的 case 分支,直到遇到 break 语句或 switch 块结束。这种特性称为“穿透”。

public class SwitchExample {
    public static void main(String[] args) {
        int number = 2;
        
        switch (number) {
            case 1:
                System.out.println("Number is 1");
            case 2:
                System.out.println("Number is 2");
            case 3:
                System.out.println("Number is 3");
                break;
            default:
                System.out.println("Number is not 1, 2, or 3");
        }
    }
}

输出结果:

Number is 2
Number is 3

在这个例子中,由于在 case 2: 之后没有 break,程序继续执行 case 3: 的语句。为了避免这种穿透现象,建议在每个 case 分支的最后加上 break 语句。

四、Java 12 引入的 switch 表达式

Java 12 引入了 switch 表达式,使得 switch 语句可以返回值,从而简化了代码。在 Java 12 及之后的版本中,可以使用箭头语法。

示例 3:使用 switch 表达式
public class SwitchExpressionExample {
    public static void main(String[] args) {
        int day = 3;
        String dayName = switch (day) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> "Wednesday";
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6 -> "Saturday";
            case 7 -> "Sunday";
            default -> "Invalid day";
        };
        
        System.out.println("The day is: " + dayName);
    }
}

在这个示例中,switch 表达式使用箭头语法,并且每个分支都返回一个值。default 分支处理所有未匹配的情况。相较于传统的 switch 语句,switch 表达式更加简洁和易读。

五、Java 13 引入的 yield 关键字

在 Java 13 及之后的版本中,yield 关键字被引入到 switch 表达式中,以便从一个分支返回一个值。这在需要复杂逻辑时非常有用。

示例 4:使用 yield 关键字
public class SwitchYieldExample {
    public static void main(String[] args) {
        int day = 3;
        String dayName = switch (day) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> {
                System.out.println("Processing Wednesday");
                yield "Wednesday";
            }
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6 -> "Saturday";
            case 7 -> "Sunday";
            default -> "Invalid day";
        };
        
        System.out.println("The day is: " + dayName);
    }
}

在这个示例中,case 3 使用了大括号来包含多条语句,并使用 yield 关键字返回一个值。这样可以在每个分支中执行更多的代码而不会失去表达式的简洁性。

六、常见问题及解决方案
  1. 穿透(Fall-through)问题

    问题:如果在 case 分支中没有使用 break 语句,程序将继续执行后续的 case 分支,直到遇到 break 语句或 switch 块结束。

    解决方案:在每个 case 分支的最后加上 break 语句,确保程序在匹配的 case 分支后跳出 switch 语句。

    switch (number) {
        case 1:
            System.out.println("Number is 1");
            break;
        case 2:
            System.out.println("Number is 2");
            break;
        case 3:
            System.out.println("Number is 3");
            break;
        default:
            System.out.println("Number is not 1, 2, or 3");
            break;
    }
    
  2. 常量表达式问题

    问题case 标签后的值必须是编译时常量,因此不能使用变量或运行时计算的值。

    解决方案:确保 case 标签后的值是编译时常量,例如字面值、枚举常量或 final 常量。

    final int CONSTANT = 2;
    
    switch (number) {
        case 1:
            System.out.println("Number is 1");
            break;
        case CONSTANT:
            System.out.println("Number is 2");
            break;
        default:
            System.out.println("Number is not 1 or 2");
            break;
    }
    
  3. 数据类型问题

    问题switch 表达式的类型和 case 标签的类型必须一致,否则会出现编译错误。

    解决方案:确保 switch 表达式和 case 标签的类型一致。Java 7 及以上版本支持 String 类型,但早期版本不支持。

    String fruit = "Apple";
    
    switch (fruit) {
        case "Apple":
            System.out.println("The fruit is an Apple.");
            break;
        case "Banana":
            System.out.println("The fruit is a Banana.");
            break;
        default:
            System.out.println("Unknown fruit.");
            break;
    }
    
  4. 忽略 default 分支

    问题:如果 switch 表达式的值未匹配任何 case 标签且没有 default 分支,程序不会执行任何 switch 语句中的代码。

    解决方案:建议始终提供一个 default 分支来处理未匹配的情况。

    switch (number) {
        case 1:
            System.out.println("Number is 1");
            break;
        case 2:
            System.out.println("Number is 2");
            break;
        default:
            System.out.println("Number is not 1 or 2");
            break;
    }
    
  5. 可读性和维护性问题

    问题:如果 switch 语句包含大量的 case 分支,代码可能变得难以阅读和维护。

    解决方案:考虑将复杂的 switch 语句重构为更简洁的方法或类,或使用 enum 类型结合 switch 语句来提高可读性。

    public enum Day {
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    }
    
    Day day = Day.WEDNESDAY;
    
    switch (day) {
        case MONDAY:
            System.out.println("Today is Monday");
            break;
        case TUESDAY:
            System.out.println("Today is Tuesday");
            break;
        case WEDNESDAY:
            System.out.println("Today is Wednesday");
            break;
        case THURSDAY:
            System.out.println("Today is Thursday");
            break;
        case FRIDAY:
            System.out.println("Today is Friday");
            break;
        case SATURDAY:
            System.out.println("Today is Saturday");
            break;
        case SUNDAY:
            System.out.println("Today is Sunday");
            break;
        default:
            System.out.println("Invalid day");
            break;
    }
    
  6. 复杂逻辑问题

    问题:有时一个 case 分支需要执行复杂的逻辑,导致代码变得臃肿。

    解决方案:可以使用 Java 13 引入的 yield 关键字,或将复杂逻辑封装到方法中,以保持 switch 语句的简洁。

    public class SwitchYieldExample {
        public static void main(String[] args) {
            int day = 3;
            String dayName = switch (day) {
                case 1 -> "Monday";
                case 2 -> "Tuesday";
                case 3 -> {
                    System.out.println("Processing Wednesday");
                    yield "Wednesday";
                }
                case 4 -> "Thursday";
                case 5 -> "Friday";
                case 6 -> "Saturday";
                case 7 -> "Sunday";
                default -> "Invalid day";
            };
            
            System.out.println("The day is: " + dayName);
        }
    }
    

通过理解和避免这些常见问题,可以更有效地使用 switch 语句,使代码更加简洁、可读和易于维护。

七、总结
  • switch 语句适用于对单个变量的多个可能值进行判断,代码更加简洁和清晰。
  • 使用 break 语句可以避免“穿透”问题。
  • Java 12 引入的 switch 表达式使得 switch 语句更加简洁和功能强大。
  • yield 关键字在 Java 13 中被引入,用于从 switch 表达式的分支中返回值,使得代码更加灵活。
  • 理解并解决常见问题,可以更有效地使用 switch 语句。

通过本文的详细介绍,希望你对 Java 的 switch 语句有了更深入的了解,能够在实际编程中灵活运用这一强大的控制流语句。


原文地址:https://blog.csdn.net/qq_38411796/article/details/140719291

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!