发布日期:2018-03-26
为什么不可以在switch语句中使用string做参数?+ 查看更多
为什么不可以在switch语句中使用string做参数?
+ 查看更多
发布日期:2018-03-10 13:31
分类:JAVA
浏览次数:233
为什么不可以在switch语句中使用string做参数?
这个功能会被添加进以后的java版本中吗?
有人可以来解释一下不能这样做的原因以及从技术方面来说明一下java@switch@语句的工作原理吗?
这个功能会被添加进以后的java版本中吗?
有人可以来解释一下不能这样做的原因以及从技术方面来说明一下java@switch@语句的工作原理吗?
回答
在距离程序员们第一次请求后至少有16年,带有string参数的switch-case语句终于可以在java SE 7中实现了。对于延迟的明确原因并没有给出,但它可能与性能有关。
在JDK7中的实现
该功能已经在javac中实现了一个“去糖化”过程;使用在case中声明的string常量这种简洁且高效的语法在编译器扩展为遵循一定模式的更复杂的代码。生成的代码使用一直存在的JVM指令。
带有string的switch语句在编译期间被翻译成两个switches语句,第一个把每个字符串映射为一个唯一的整数——它的位置和原始的switch一样。这是通过首先打开标签的哈希码来实现的,相应的case选项是一个测试字符串相等的if语句,如果在哈希码上有冲突,则测试是级联的if-else-if语句。第二个switch反射原始的源代码,但用相应的位置替换case标签。这两个过程易于保持原始switch语句的流程控制。
在JVM中的switches
对于在switch语句上更深入的技术,你可以参考JVM的说明书,上面描述了switch语句的编译原理。简单来说,取决于用在case上的常量的稀疏性,有两种不同的JVM指令被用于switc语句。两种case都依赖于使用整数常量来高效执行。
如果常量值分布很密集,它们会被用作一个(减去最低值之后的)索引添加到一个指令指针表中——tableswitch指令。
如果常量值分布很稀疏,则执行对于case的二分查找——lookupswitch指令。
对于一个switch语句在string对象上的“去糖化过程”,两种指令都可能被用到。lookupSwitch适合于有哈希码的第一个switch来知道case的原始位置。而生成的序数则自然适合tableswitch。
这两个指令都要求分配给case选项一个整数常量来在编译期进行排序。在运行期间,当tableswitch的复杂度O(1)表现地比lookupswitch<的复杂度O(log(n))更好时,但它需要一些分析来确定是否表格足够密集来证明在空间-时间上的权衡。Bill Venners写过一篇包含了更多细节的很好的文章,并且包含了从底层来看其他的java流程控制指令。
JDK 7之前
在JDK 7之前,num近似于一个带有string的switch语句,它在每种enum类型上使用由编译器生成的静态的valueOf方法。举例如下:
Pill p = Pill.valueOf(str); switch(p) { case RED: pop(); break; case BLUE: push(); break; }