此功能是否将在以后的Java版本中使用?
有人可以解释为什么我不能这样做吗,就像Java switch
语句起作用的技术方式一样?
带有String
案例的switch语句已在Java SE 7中实现,至少在首次提出要求后的 16年。没有提供延迟的明确原因,但可能与性能有关。
在JDK 7中实现
现在,该功能已javac
通过“脱糖”过程实现。String
在case
声明时使用常量的干净,高级语法在编译时扩展为遵循模式的更复杂的代码。生成的代码使用始终存在的JVM指令。
switch
带有Stringcase
的A 在编译期间转换为两个开关。第一个将每个字符串映射到一个唯一的整数-它在原始开关中的位置。这是通过首先打开标签的哈希码来完成的。相应的情况是if测试字符串是否相等的语句;如果哈希上有冲突,则测试为级联if-else-if。第二个开关在原始源代码中进行镜像,但是用相应的位置替换了大小写标签。此两步过程使保留原始交换机的流量控制变得容易。
在JVM中切换
有关的更多技术深度switch
,请参考JVM规范,其中描述了switch语句的编译。简而言之,有两种不同的JVM指令可用于切换,具体取决于案例使用的常量的稀疏性。两者都依赖于每种情况下使用整数常量来有效执行。
如果常量密集,则将它们用作指令指针表(指令)的索引(减去最小值后)tableswitch
。
如果常量稀疏,则对lookupswitch
指令的正确大小写进行二进制搜索。
在switch
对String
物体进行脱糖时,可能会同时使用这两种指令。在lookupswitch
对散列码的第一开关以找到的情况下的原始位置是合适的。由此产生的序数是自然适合tableswitch
。
两条指令都要求在编译时对分配给每种情况的整数常量进行排序。在运行时,虽然O(1)性能tableswitch
一般显得比更好O(log(n))
的性能lookupswitch
,它需要一些分析,以确定该表是否是密集足以证明时空权衡。Bill Venners撰写了一篇很棒的文章,其中更详细地介绍了此内容,同时还深入介绍了其他Java流程控制指令。
在JDK 7之前
在JDK 7之前,enum
可以近似String
基于的开关。这将使用编译器针对每种类型生成的静态valueOf
方法enum
。例如:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}
问题内容: 为什么下面的代码: 给出错误: 在循环外继续 问题答案: 失败是switch语句的标准行为,因此,在switch语句中使用Continue没有意义。Continue语句仅在for / while / do..while循环中使用。 根据我对您意图的理解,您可能想写: 我还建议您将默认条件放在最后。 编辑:continue语句不能在switch语句中使用并不完全正确。(带有理想标记的)
问题内容: 我决定使用Swift的case语句和元组。它看起来像是该语言的较酷功能之一。 我决定玩月/日/年元组。令我惊讶的是,我不能在switch语句中使用常量元组值作为案例。这是一个示例(可以粘贴到Playground中并运行) 注释掉的代码不会编译(如果重要的话,在Xcode 6.3中)。在下面的情况下(我分别列出了joesBirthday元组的所有元素)更难键入且更难阅读,确实可以工作)
问题内容: 我想分割一个具有如下内容的字符串: 但是当我使用时: 它不能识别$并且不分割字符串,但是当我用$像X这样的字母替换$时,它可以工作。有人有什么主意吗? 问题答案: split函数需要一个正则表达式(而不是字符串)进行匹配。您的正则表达式使用特殊字符-在本例中为’$’-因此您需要对其进行更改以转义该字符: 还要注意,split返回一个字符串数组- 字符串是不可变的,因此无法修改。对Str
本文向大家介绍如何在C#中的switch语句中使用字符串,包括了如何在C#中的switch语句中使用字符串的使用技巧和注意事项,需要的朋友参考一下 switch语句允许针对值列表测试变量是否相等。每个值称为大小写,并针对每个开关大小写检查打开的变量。 示例 这是在switch语句中使用字符串的示例- 输出结果 这将产生以下输出-
问题内容: The Go Playground上可用的程序读取 并产生一个错误 我了解是字符串的“零值”。我不明白为什么我不能分配给我的。 问题答案: 简单的答案是, 在语言规范中未将其定义为类型的有效值。 …但是也许您想要更长的答案? 是指针,接口,通道,切片,映射和函数类型的零值,它表示 未初始化的 状态。 考虑以下变量声明: 所有这些变量都有一个代表未初始化状态的值,这很自然。已被声明为指针