详解Java12新增语法switch表达式

引言

在学习分支语句的时候,我们都学过 switch 语句,相比于 if-else 语句,他看起来更加整洁,逻辑更加清晰,Java中当然也给我们提了相关的 switch 方法。但是Java的强大之处在于,他对这一语句结构进行了拓展。在Java 12中,Java新引入了switch表达式Switch Expressions,我们都知道,switch 语句如果漏写一个 break,那么逻辑往往就跑偏了,这种方式既繁琐,又容易出错。那么Switch Expressions为我们提供勾勒出了Java 语法进化的一个趋势,将开发者从复杂繁琐的低层次抽象中逐渐解放出来,以更高层次更优雅的抽象,既降低代码量,又避免意外编程错误的出现,进而提高代码质量和开发效率。下面我将对传统的switch语句和switch表达式做出对比,并介绍switch表达式的用法。

对比

例如,根据用户输入的年份和月份,判断这个月一共有多少天,传统switch语句代码如下:

package day_11_25;

import java.time.LocalDate;
import java.util.Scanner;

/**
 * @author soberw
 */
public class Switch {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入年份:");
        int year = sc.nextInt();
        System.out.print("请输入月份:");
        int month = sc.nextInt();
        int day = 31;
        switch (month) {
            case 4:
            case 6:
            case 9:
            case 11:
                day = 30;
                break;
            case 2:
                day = (LocalDate.of(year, month, 1).isLeapYear()) ? 29 : 28;
                break;
            default:
                break;
        }
        System.out.printf("%d年%d月有%d天%n", year, month, day);
    }
}

运行测试:
在这里插入图片描述
使用switch表达式后:

package day_11_25;

import java.time.LocalDate;
import java.util.Scanner;

/**
 * @author soberw
 */
public class SwitchExpression {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入年份:");
        int year = sc.nextInt();
        System.out.print("请输入月份:");
        int month = sc.nextInt();
        int day = switch (month) {
            case 4, 6, 9, 11 -> 30;
            case 2 -> (LocalDate.of(year, month, 1).isLeapYear()) ? 29 : 28;
            default -> 31;
        };
        System.out.printf("%d年%d月有%d天%n", year, month, day);
    }
}

运行测试:
在这里插入图片描述

用法分析

那么switch语句与switch表达式最大的区别就是switch可以有返回值了,这也就是为什么我用的时候可以"int day = "了,每一个分支只需要决定具体的返回值是什么,不需要考虑如何使用这个值。而全程只需要一次赋值操作。代码整体变得更简洁、紧凑、清晰。

switch表达式也可以使用 : ,在这种情况下,各个分支必须用break关键字返回值。若使用->这种形式就不需要break,但是:和->不可以混合使用

需要注意的是:

switch表达式必须有default,你可以理解为我们在声明变量的时候必须加一个默认值一样

代码块与yield关键字

那么如果我们想加入其他操作呢,比如在上面案例中,当月份是2月时,我除了想要给day赋值,我还想多输出一句“现在是二月!”那这时候就可以使用代码块了,形式如下:

package day_11_25;

import java.time.LocalDate;
import java.util.Scanner;

/**
 * @author soberw
 */
public class SwitchExpression2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入年份:");
        int year = sc.nextInt();
        System.out.print("请输入月份:");
        int month = sc.nextInt();
        int day = switch (month) {
            case 4, 6, 9, 11 -> 30;
            case 2 -> {
                //这里是代码块
                System.out.println("现在是二月!");
                yield (LocalDate.of(year, month, 1).isLeapYear()) ? 29 : 28;
            }
            default -> 31;
        };
        System.out.printf("%d年%d月有%d天%n", year, month, day);
    }
}

运行结果:
在这里插入图片描述
在执行当前分支的时候,如果我们直接返回值,就可以直接写值就行了,但如果我们想在返回值之前再执行其他操作呢,那就必须使用代码块,用{}括起来,最后通过yield关键字将值返回出来就ok了

注意!!!

使用了代码块之后,{}外面一定不要加;(本人已踩坑。。。)

posted @ 2022-02-09 19:45  soberw-  阅读(483)  评论(0编辑  收藏  举报