深入解析 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 语句有了更深入的了解,能够在实际编程中灵活运用这一强大的控制流语句。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/50411.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Godot入门 01Godot介绍

Unity大神,YouTube百万游戏开发者的启蒙老师,Brackeys,携 Godot 新手教程,正式回归。 转自:https://youtu.be/LOhfqjmasi0?si4RguI6-pXHZ2mk9K 资产:https://brackeysgames.itch.io/brackeys-platformer-b…

病理多示例学习仓库介绍(持续更新中)

开源项目介绍:MIL_BASELINE 项目概览 MIL_BASELINE 是一个集成了多种多实例学习方法(MIL)的统一框架库,旨在简化多实例学习模型的开发与应用。它不仅整合了多种MIL方法,还提供了统一的数据集接口和常用的数据集划分方…

C++的编译方式和文件扩展名,C++的头文件,以及C++的标准输入和输出

本文介绍C++的编译方式和文件扩展名,C++的头文件,以及C++的标准输入和输出 1.编译方式和文件扩展名 2.头文件 3.标准输入输出 //vi 01first.cpp#include <iostream>int main(void) {std::cout<<"hello world"<<std::endl;return 0;}1.1编译方式…

【linux】Shell脚本三剑客之grep和egrep命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

LK漏感值在网络变压器测试中是否有很大的作用?

今天客户一个产品异常问题&#xff0c;就是说LK漏感值严重超标产品规格书参数&#xff0c;今天我们讲讲这个参数在网络变压器其中的影响。LK漏感值在网络变压器的测试和性能评估中扮演着重要的角色。漏感&#xff0c;或称为漏磁场感抗&#xff0c;是指变压器中不参与主要能量传…

2024.7.24

预处理 在计算机编程和算法设计中&#xff0c;“预处理”通常指在正式的处理或计算之前&#xff0c;对数据或操作进行的一些预先的处理和准备工作。 目的 预处理的目的通常包括&#xff1a; 优化性能&#xff1a;通过提前计算或整理一些数据&#xff0c;减少后续主要计算过…

万字长文说说C#和Rust_Cangjie们的模式匹配

C#11新增列表模式后&#xff0c;这个从C#6就开始的特性&#xff0c;算是拼接好了模式匹配的最后一块拼图。对比Swift、Rust或Cangjie这类先天支持模式匹配的语言&#xff0c;能否一战&#xff1f;今天就来全面battle一下。Swift、Rust和Cangjie的模式匹配&#xff0c;一肪相承&…

springboot会员信息管理系统-计算机毕业设计源码38258

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3开发技术 1.3.1 Spring Boot框架 1.3.2 Java语言 1.3.3 MySQL数据库 1.4论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统功能分析 2.4 系统用例分析…

代码审计:Bluecms v1.6

代码审计&#xff1a;Bluecms v1.6 漏洞列表如下(共计32个漏洞&#xff0c;附Exp&#xff0c;按时间顺序)&#xff1a; 未完待续… 1、user.php 766行处存在任意文件删除漏洞 Exp:http://127.0.0.3/bluecms/user.php?actedit_user_info Post&#xff1a;face_pic32.php el…

动静资源的转发操作

目录 Nginx中的location指令 静态资源的转发 动态资源的转发 注意事项 深入研究 如何在Nginx中实现对特定后缀文件的静态资源进行反向代理&#xff1f; Nginx中location指令的优先级是怎样确定的&#xff1f; 为什么在使用proxy_pass时要区分是否带有斜杠&#xff1f; N…

《Java初阶数据结构》----8.<java对象的比较总结>

目录 前言 一、Java对象的比较 1.1基本类型的比较 1.2 对象比较的问题&#xff08;与equals&#xff09; 1.3对象的比较 &#xff08;三种常用方式&#xff09; 1.重写equals方法 2.基于Comparble接口类的比较 3.基于比较器比较&#xff08;Comparator接口&#xff09; …

秒懂C++之string类(下)

目录 一.接口说明 1.1 erase 1.2 replace&#xff08;最好别用&#xff09; 1.3 find 1.4 substr 1.5 rfind 1.6 find_first_of 1.7 find_last_of 二.string类的模拟实现 2.1 构造 2.2 无参构造 2.3 析构 2.4.【】运算符 2.5 迭代器 2.6 打印 2.7 reserve扩容 …

大模型算法面试题(十二)

本系列收纳各种大模型面试题及答案。 1、领域模型Continue PreTrain数据如何选取 在领域模型的Continue PreTrain&#xff08;持续预训练&#xff09;过程中&#xff0c;数据选取是一个至关重要的步骤&#xff0c;它直接影响模型在特定领域上的性能和泛化能力。以下是一些关于…

react native FlatList 组件滚动问题

版本"react-native": "0.74.2", <FlatListstyle{{width: 100%}}ref{flatListRef}data{list}renderItem{chatItem}keyExtractor{item > item.id}// onScroll{handleScroll}onContentSizeChange{() > {// 内容大小变化时&#xff0c;如果未手动滚动…

JavaScript在现代Web开发中的高级特性与趋势

介绍随着Web技术的飞速发展&#xff0c;JavaScript的角色日益重要&#xff0c;不仅限于前端逻辑处理&#xff0c;还涉及到后端服务、移动应用等多个领域。阐述掌握JavaScript高级特性对于开发高性能、可扩展Web应用的重要性。 1. ES6新特性概览 箭头函数&#xff1a;更简洁的…

Transformer-Bert---散装知识点---mlm,nsp,较之经典tran的区别和实际应用方式

本文记录的是笔者在了解了transformer结构后嗑bert中记录的一些散装知识点&#xff0c;有时间就会整理收录&#xff0c;希望最后能把transformer一个系列都完整的更新进去。 1.自监督学习 bert与原始的transformer不同&#xff0c;bert是使用大量无标签的数据进行预训练&#…

batch norm记录

文章目录 概要整体架构流程训练阶段推理阶段模型中使用的注意事项 概要 面试百度时候被问到了BN 内部详细的训练阶段&#xff0c;推理阶段的计算过程。没回答好&#xff0c;来记录一下 推荐一下b站up: Enzo_Mi。视频做的确实不错 bn 讲解视频 整体架构流程 训练阶段 均值和标…

【C/C++】printf和cout的区别

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

【公式解释】《系统论》《控制论》《信息论》的共同重构:探索核心公式与深度解析

《系统论》《控制论》《信息论》的共同重构:探索核心公式与深度解析 关键词:系统论、控制论、信息论、状态空间方程、系统矩阵。 Keywords: System theory, Control theory, Information theory, State-space equations, System matrices. 核心公式与三论共同之处 在系统…

C++初阶学习——探索STL奥秘——标准库中的string类

1. 为什么学习string类&#xff1f; 在我们学习C语言的时候&#xff0c;有一个点是非常难处理的&#xff0c;那就是字符串&#xff0c;在我们对字符串访问&#xff0c;增删查改时都是非常不便的&#xff0c;所以我们封装了一个string类主要来处理字符串有关的问题 2. 标准库中…