JDK 12:实际中的切换语句/表达式

我的上一篇文章“ 玩JDK 12的Switch表达式 ”讨论了如何使用JDK 12 Early Access Builds尝试JEP 325 switch 表达式语句,并提供了一个简单的示例。 这篇文章使用相同的JDK 12 Early Access Build 10来演示switch表达式和增强的switch语句的不同功能。

我在博客文章“ 通过引入switch表达式来增强Java switch语句 ”中使用了2×2网格,以说明新的“箭头”语法(“ switch标为规则”)可以与switch 语句switch表达式一起使用。按照JEP325。类似地,按照JEP 325,传统的“冒号”语法(“带开关标记的语句组”)也可以与switch 表达式switch语句一起使用。 换句话说,结肠的存在( :并不一定意味着一个switch的“箭头”的声明 ,并存在( ->并不一定意味着一个switch 表达 。 为了方便起见,我在前面的文章中提供了表格的改编版本。

声明
(“交换机的非本地控制流_out_ [继续到封闭循环,带有标签的中断,返回]”)
表达
(总计:返回一个值)
开关标签声明组
(“结肠”)
(启用穿透)
switch我们知道和“爱”,但增强了 break返回的值类似于return
开关标签规则
(“箭头”)
(防止掉线)
语句/冒号的“语法简写”(上)以及
  • “消除了“休息”的烦恼”
  • “隐式防止所有形式的失败”
  • “避免了电流开关范围的混乱”
箭头( -> )指向返回值

使用JDK 12 Early Access Build ,可以方便地试用新的switch 表达式 ,我们还可以试用传统的和增强的switch 语句版本。

传统开关声明

即使启用了JDK 12预览( --enable-preview ),我们仍然可以使用我们“了解并爱着”的传统switch 语句 。 下面显示了这个传统 switch语句的示例,即使启用了JDK 12语言功能预览,该语句也可以成功编译和执行。

/*** Demonstrate traditional switch statement assigned to* local variable.*/
public static void demonstrateTraditionalSwitchStatement()
{out.println("Traditional Switch Statement:");final int integer = 3;String numericString;switch (integer){case 1 :numericString = "one";break;case 2 :numericString = "two";break;case 3:numericString = "three";break;default:numericString = "N/A";}out.println("\t" + integer + " ==> " + numericString);
}

这篇文章中显示的此代码以及所有其他代码示例可在GitHub上找到 。 这个特定的示例显示了传统switch语句设置局部变量值的常见用法。 我之所以选择此用例,是因为新的switch表达式是实现此目的的一种改进方法。

增强型开关声明

如前所述,我们可以在增强的 switch 语句中使用新的“箭头”语法(“带有开关标签的规则”)。 在使用--enalved-preview的JDK 12 Early Access Build 10上编译并运行的下一个代码示例中显示了这一点。

/*** Demonstrate enhanced switch statement used to assign* a local variable.*/
public static void demonstrateEnhancedSwitchStatement()
{out.println("Enhanced Switch Statement:");final int integer = 2;String numericString;switch (integer){case 1 -> numericString = "one";case 2 -> numericString = "two";case 3 -> numericString = "three";default -> numericString = "N/A";}out.println("\t" + integer + " ==> " + numericString);
}

最后一个示例显示了该switch仍然用作语句 ,但是在这种情况下,它利用了“箭头”语法(“标签规则”)来完成其切换,而没有明确指定break 。 这不仅减少了代码量,而且更重要的是具有不允许经常令人恐惧的switch “掉线”的优点。 简而言之, 增强后的 switch 语句的工作方式类似于当前/传统的switch语句,但是没有传统版本的潜在缺陷。

新开关表达式通过中断返回值

JEP 325除了增强当前的switch语句以允许指定switch语句而没有掉线的风险之外,还引入了在switch 表达式中使用switch关键字的概念。 Java教程的“ 表达式,语句和块 ”页面介绍了语句操作之间的区别。 为了便于讨论,该教程中的两个重要观察结果是(我加粗了强调):

  1. 表达式是由变量,运算符和方法调用组成的结构, 其结果为单个值 。”
  2. “ Java编程语言允许您从各种较小的表达式中构造复合表达式 ,只要该表达式的一部分所需的数据类型与另一部分的数据类型匹配即可。”

下一个代码清单演示了如何使用JDK 12 Early Access Build 10和--enable-preview替换上面显示的代码,该代码使用switch 语句将一个值分配给较早声明的局部变量,而该语句使用一个在单个语句中switch 表达式以将其结果值分配给局部变量。

/*** Demonstrate switch expression using colons and breaks.*/
public static void demonstrateSwitchExpressionWithBreaks()
{final int integer = 1;out.println("Switch Expression with Colons/Breaks:");final String numericString =switch (integer){case 1 :break "uno";case 2 :break "dos";case 3 :break "tres";default :break "N/A";};out.println("\t" + integer + " ==> " + numericString);
}

刚刚显示的代码示例演示了switch 表达式的使用,该表达式与前面显示的传统switch语句示例非常相似。 但是,有几个明显的不同。 区别在于此switch表达式返回的结果分配给局部变量“ numericString ”。 第二个区别直接与switch 表达式能够返回一个值有关,在于break子句现在每个都有要在break关键字后立即指定的相关case要返回的值。 本质上, switch 表达式break就像Java方法return

通过标签规则的新开关表达式返回值

只是示出的实施例表明,人们可以从一个返回值switch有类似结肠表达式: )和break语法什么一个很可能与使用switch的语句。 除了熟悉之外,此方法的另一个优点是可以在返回单个值之前为单个case指定多个语句。 但是,在大多数情况下,使用前面讨论的“箭头”语法从switch 表达式返回值可能会变得很流行,因为它不会遭受掉线的风险,并且可以避免通常与传统switch语句相关的范围意外。 下一个代码清单演示了新的switch 表达式如何使用“标签规则”(“箭头”语法)而不是冒号并break以优雅地返回该switch的单个解析值。

/*** Demonstrate switch expressions using "arrow" syntax.*/
public static void demonstrateSwitchExpressionWithArrows()
{final int integer = 4;out.println("Switch Expression with Arrows:");final String numericString =switch (integer){case 1 -> "uno";case 2 -> "dos";case 3 -> "tres";case 4 -> "quatro";default -> "N/A";};out.println("\t" + integer + " ==> " + numericString);
}

上面的四个示例演示了2×2网格中所示的每种情况。 本文的其余部分将讨论使用JDK 12 Early Access Build 10尝试switch表达式和语句时的一些其他观察结果。

可以为单个情况指定多个常量

2×2网格中的四个象限中的任何一个都允许将多个常数与单个case相关联。 在下一个代码清单中对此进行了演示,该清单在启用“预览语言功能”的情况下与JDK 12 Early Access Build 10一起编译和运行。

/*** Demonstrate that multiple constants can be associated with* a single {@code case} and used in conjunction with a* {@code switch} expression that uses the "arrow" syntax.*/
public static void demonstrateLabelRulesWithSharedCases()
{final int integer = 7;out.println("Multiple Case Labels:");final String numericString =switch (integer){case 0 -> "zero";case 1, 3, 5, 7, 9 -> "odd";case 2, 4, 6, 8, 10 -> "even";default -> "N/A";};out.println("\t" + integer + " ==> " + numericString);
}/*** Demonstrate that multiple constants can be associated with* a single {@code case} and used in conjunction with a* {@code switch} statement that uses the traditional colon and* {@code break} syntax.*/
public static void demonstrateBlockedStatementsWithSharedCases()
{final int integer = 6;out.println("Multiple Case Labels:");String numericString;switch (integer){case 0:numericString = "zero";break;case 1, 3, 5, 7, 9:numericString = "odd";break;case 2, 4, 6, 8, 10:numericString = "even";break;default:numericString = "N/A";};out.println("\t" + integer + " ==> " + numericString);
}

不能混用“箭头”(“标签规则”)和冒号/中断(“语句组”)

JDK 12 Early Access Build 10编译器( javac )不允许混合使用“箭头”语法和传统的冒号/ break语法。 尝试将这些混合使用会导致错误消息:“ 错误:开关中使用的种类不同 ”。 接下来显示了一个示例代码,该代码无法编译并显示此特定错误消息。

/*** WARNING - This does NOT compile, even with JDK 12 Early* Access Builds and --enable-preview because JEP 325 does* not allow the "arrow" syntax to be mixed with the* traditional colon/break syntax.*/
public static void demonstrateMixed()
{final int integer = 3;String numericString;switch(integer){case 1 :numericString = "one";break;case 2 -> numericString = "two";default -> numericString = "N/A";}return numericString;
}

Switch语句的中断无法返回值

新的switch 表达式返回一个值,当switch表达式使用冒号和break方法时,将在break关键字之后立即指定该返回值。 因为传统的switch 语句不返回值,所以尝试使与switch 语句关联的break指定返回值是编译时错误。 错误(“错误:意外的值中断”)可以用以下代码重现。

/*** WARNING - This does NOT compile, even with JDK 12 Early* Access Builds and --enable-preview because it is* nonsensical to have a "statement" return a value; that* is what an expression should be used for.*/
public static void demonstrateSwitchStatementReturnedLabel()
{final int integer = 4;switch (integer){case 1:break "one";case 2:break "two";case 3:break "three";default:break "N/A";};
}

当尝试使用带有指定标志--enable-preview-release 12 JDK 12 Early Access Build 10的javac编译器来编译以上代码时,错误消息“ error:意料之外 ”的四个实例(对应于三种case加上一种default价值突破 ”可见。 毫不奇怪,将switch分配给局部变量(并有效地将语句转换为表达式 )的简单更改就可以编译该代码。 换句话说,将上面的代码更改为下一个代码清单中的代码可以使其编译并成功运行。

/*** This demonstrates that a {@code switch} "expression" is* able to (and expected to) provide the "return" value for* a given {@code case} and {@code default} instead of being* a compiler error as it was for the "statement" example* demonstrated in method* {@link #demonstrateSwitchStatementReturnedLabel()}.*/
public static void demonstrateSwitchExpressReturnedLabel()
{final int integer = 4;final String numericString =switch (integer){case 1:break "one";case 2:break "two";case 3:break "three";default:break "N/A";};
}

当前的JEP 325文本包含有关此break行为与方法return相似的讨论。 该讨论指出, switch 语句在其break s之后不需要返回值的情况类似于返回void的方法。 switch 表达式应返回非void值。

Switch语句的“箭头”语法必须指向一条语句

即使向javac编译器提供了--enable-preview-release 12 ,以下代码也无法在JDK 12 Early Access Build 10中进行编译。

/*** WARNING - This does not compile, even with JDK 12 Early* Access Builds and --enable-preview and reports error message* "error: not a statement" because it is expecting a* {@code switch} "statement" but what is being provided to each* {@code case} is NOT a statement.*/
public static void demonstrateSwitchStatementReturnedValueViaLabelRule()
{final int integer = 5;switch (integer){case 1 -> "one";case 2 -> "two";};out.println(numericString);
}

上面的代码无法编译,并且报告的错误消息是“错误:不是语句”。 这是因为在此示例中将switch用作语句,但是“箭头”语法是“指向”文字字符串而不是有效的Java语句。

所有可能性都必须在switch表达式中指定

因为switch 表达式需要返回一个非void值,所以switch 表达式必须为其可能打开的所有可能值指定case 。 实际上,这很可能是通过default来实现的,以捕获未用case明确指定的所有可能性。 使用传统的switch语句,不需要确保所有可能打开的值都由casedefault值覆盖,并且有时会导致某些情况,例如我在博客文章“ Log Unexpected Switch Options ”中所述。

以下代码违反了以下规则: switch 表达式必须指定casedefault值的所有可能值:

/*** WARNING - This method will not compile even with JDK 12* Early Access Build 10 with --enable-preview because of* error; "the switch expression does not cover all possible* input values".*/
public static void demonstrateLackingCaseInSwitchExpression()
{final int integer = 5;String numericString =switch (integer){case 1 -> "one";case 2 -> "two";};out.println(numericString);
}

刚刚显示的代码将无法编译,并且因果错误消息为“错误:开关表达式未涵盖所有可能的输入值。”

JEP 325对交换机未来使用的影响

考虑到Java中除了switch 语句之外还有可用的switch 表达式所带来的可能性,并考虑到可以与switch表达式或语句一起使用的新“箭头”语法所提供的优势,开始思考何时进行有趣的事情。上面2×2网格中的每个象限最有利。 总的来说,我相信我会发现自己经常使用带有“箭头”语法(“标签规则”)的switch 表达式 ,同时也经常使用带有“ arrow”语法的增强型switch 语句 。 我怀疑将来我会很少使用传统的:break )语法。 即使在特定case有多个语句要执行时,我也可能会将这些语句分解为单个方法,在这种case使用“箭头”语法进行调用。 这将使我受益于更明显的作用域并避免掉线的风险。 鉴于现在可以为单个case指定多个常量,即使在多个案例导致相同结果的情况下,也不再需要穿透。

其他资源

  • JEP 325:开关表达式(预览)
  • JEP 325规范:开关表达式
  • JDK 12抢先体验版
  • JDK语言功能预览:切换表达式
  • 玩JDK 12的Switch表达式
  • 通过引入switch表达式来增强Java switch语句
  • 切换表达式到Java吗?
  • 切换表达式-收集线程
  • LJC演讲的少量反馈
  • GitHub上这篇文章的示例

翻译自: https://www.javacodegeeks.com/2018/09/jdk-12-switch-statements-expressions.html

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

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

相关文章

broker可以禁用吗 time_Win8.1系统Runtime Broker是什么进程?可以禁用吗?

我们知道电脑一开启就有很多进程了,其中有一个Runtime Broker是大家比较疑惑的,很多人会问Win8.1系统Runtime Broker是什么进程?可以禁用吗?带着这两个问题,小编现在就来为大家讲解一下。一、RuntimeBroker进程介绍Run…

2. linux的日志文件在哪个目录,位于/var/log目录下的20个Linux日志文件

如果你多数时间都在使用Linux系统,那么你有必要知道系统的日志文件位于哪里,以及每个日志文件是关于哪些内容的。在系统正常的时候学习理解各种日志文件的内容,有助于在遇到紧急情况时通过日志文件定位问题所在。/etc/rsyslog.conf文件决定了…

linux内核4.4和4.5,[图]Linux Kernel 4.5系列第4个维护版本发布

Greg Kroah-Hartman表示:“我今天宣布了Linux 4.5.4内核,所有Linux 4.5内核系列用户必须尽快升级。已经升级的4.5.y git tree能够在git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-4.5.y中获取,也能通过访问h…

python字符串下标截取_python 用下标截取字符串的实例

python 用下标截取字符串的实例运行环境: win7 64位python 2.7pycharmpython 源码如下# -*- coding: utf-8 -*-str 0123456789print(str[0:3])print(str[0:-1])print(str[-1])print(str[2:5])print(str[6:-1])print(str[6:])运行效果如下:0120123456789…

linux正则表达式脚本实例,PowerShell中正则表达式使用例子

本文介绍PowerShell中正则表达式的使用,PowerShell的正则表达式与微软其它语言的正则表达式是一样的,使用非常方便。正则表达式本身是怎么回事,本文不做讨论,反正PowerShell还是用的微软的那一套正则表达式规则,学VB、…

天津python招聘信息网_【天津-滨海新区Python招聘_最新热搜天津-滨海新区Python人才招聘信息】-前程无忧...

学历要求:硕士|工作经验:3-4年|公司性质:上市公司|公司规模:150-500人专业:计算机、自动化、软件工程、图形图像学或相关专业 语言:c c c# java 数据库 算法 工作经验:3年以上 岗位专业能力&…

前端---初始常用的 html 标签

1. 常用的 html 标签 <!-- 1、成对出现的标签&#xff1a;--><h1>h1标题</h1> <div>这是一个div标签</div> <p>这个一个段落标签</p><!-- 2、单个出现的标签&#xff1a; --> <br> <img src"images/pic.jpg&qu…

linux开机自动启动开机日志,设置linux开机自动运行脚本

实现目标&#xff1a;在Linux启动时&#xff0c;自动运行位于普通用户test1根目录下的脚本程序test.py&#xff0c;该程序会在每次执行时自动向本地日志文件追加一条记录&#xff0c;源码如下&#xff1a;from datetime import datetimenow datetime.now()f open(test.log, a…

java自定义方法参数注解_Java方法中的参数太多,第1部分:自定义类型

java自定义方法参数注解我认为构造函数和方法中冗长的参数列表是Java开发中的另一个“ 危险信号 ”&#xff0c;就逻辑和功能而言&#xff0c;它们不一定是“错误的”&#xff0c;但通常暗示当前或将来出现错误的可能性很高。 在一小部分帖子中&#xff0c;我介绍了一些可用于减…

5 zabbix 添加host_Zabbix 快速上手——添加 Agent 主机

Zabbix-Server 安装完成之后&#xff0c;下一步需要添加主机才能看到数据。安装Zabbix AgentZabbix Agent 的作用是将服务器的数据发送给 Zabbix Server&#xff0c;所以只需要在需要监控的主机上安装 Zabbix Agent 就够了。因为我的环境是&#xff1a;Ubuntu 18.04、Nginx、My…

linux 编译hadoop,linux centos 安装编译hadoop2.7.1

因为Apache hadoop 只提供了32位的包&#xff0c;所以需要自己编译64位的包&#xff0c;下面是编译步骤所需要的包6&#xff1a;java 1.7下面是具体安装&#xff1a;1&#xff1a;Java安装安装之前请卸载系统自带的jdk,openjdkexport M3_HOME/home/data/app/apache-maven-3.3.9…

使用Spring Data Cassandra缓存的预备语句

今天&#xff0c;我有一篇简短的文章&#xff0c;内容涉及在Spring Data Cassandra中使用Prepared Statements。 Spring为您提供了一些实用程序&#xff0c;使您可以更轻松地使用“预备语句”&#xff0c;而不必依靠自己使用Datastax Java驱动程序手动注册查询。 Spring代码提供…

域名是如何被墙的_如何快速搭建属于自己的个性网站?

说明一直以来都是用GithubPage搭建的博客&#xff0c;因为服务器在国外&#xff0c;访问速度一直比较慢&#xff0c;再后来有一批服务器被墙掉了导致国内网络环境直接无法访问。这里可以多说一句&#xff0c;GithubPage跟Github用的可以不是同一IP地址服务器&#xff0c;被墙很…

linux内核函数open源码,open()在Linux内核的实现(1)-基本实现

原标题&#xff1a;open()在Linux内核的实现(1)-基本实现1.基本说明在用户态使用open()时&#xff0c;必须向该函数传入文件路径和打开权限。这两个参数传入内核后&#xff0c;内核首先检查这个文件路径存在的合法性&#xff0c;同时还需检查使用者是否有合法权限打开该文件。如…

php禁止代理ip访问_php禁止某ip或ip地址段访问的方法

本文实例讲述了php禁止某ip或ip地址段访问的方法&#xff0c;分享给大家供大家参考。具体分析如下&#xff1a;因为还没有深入学习Apache和nginx 所以用PHP写了一个可以禁用地址的小程序使用时只需&#xff1a;即可禁用单个ip如下&#xff1a;//禁用ip地址$ip$_SERVER["RE…

嵌入式linux图形系统设计,轻量级嵌入式Linux图形系统设计与实现

摘要&#xff1a;图形用户界面(GUI)是人机交互界面(MMI)的重要表现形式,它不仅提供了丰富的图像信息,而且提高了用户同嵌入式设备的交互效率。随着嵌入式技术的广泛应用和嵌入式硬件的快速发展,人们对嵌入式设备的需求日益增多,嵌入式图形用户界面的作用也越来越重要。 大多数嵌…

无服务器-构建现代应用程序的新方法

对无服务器/功能即服务/云功能技术感到好奇&#xff0c;但是还没有机会深入研究&#xff1f; 想知道所有的兴奋是什么&#xff1f; 无服务器并不意味着没有服务器。 这是构建现代应用程序的新方法。 观看此视频&#xff0c;以了解有关构建现代应用程序的这种新方法的更多信息。…

linux 查看其他磁盘分区,Linux 查看磁盘分区.pdf

Linux 查看磁盘分区作者&#xff1a;北南南北来自&#xff1a;LinuxSir.Org的&#xff0c;不仅仅是查看磁盘的分区表&#xff0c;而且也能进行磁盘分区的操作&#xff1b;但在本文&#xff0c;我们只讲磁盘分区的查看&#xff0c;以及分区的使用情况的查看&#xff1b;本文只是…

python 对象锁_也许你对 Python GIL 锁的理解是 错的。

摄影&#xff1a;产品经理甜白与草莓更配~我刚到现在这个公司时&#xff0c;听到当时一个高级工程师(现已离职)大声地跟他旁边的同事说&#xff1a;Python 有 GIL 锁&#xff0c;所以它的多线程实际上是单线程&#xff0c;所以写多线程代码不用考虑线程冲突&#xff0c;不用加…

linux下强制取消nfs挂载目录,强制卸载无响应的nfs挂载目录

强制卸载无响应的nfs挂载目录在日常的运维中, 经常有需要使用 nfs 挂载远程服务器目录的需求, 但是照我个人实际使用的经验来看, nfs 并不是"一劳永逸", 故障率还是蛮高的, 其中最长遇到的就是由于网络原因/远程 nfs 服务器原因或其他原因导致的 nfs 客户端与 nfs 服…