为什么我不能在字符串上使用 switch 语句? [英] Why can't I use switch statement on a String?

查看:43
本文介绍了为什么我不能在字符串上使用 switch 语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以后的 Java 版本会加入这个功能吗?

Is this functionality going to be put into a later Java version?

有人可以解释为什么我不能这样做,例如 Java 的 switch 语句工作的技术方式吗?

Can someone explain why I can't do this, as in, the technical way Java's switch statement works?

推荐答案

String case 的 Switch 语句已经在 Java SE 7,至少 16 年 在他们第一次被请求之后.没有提供延迟的明确原因,但这可能与性能有关.

Switch statements with String cases have been implemented in Java SE 7, at least 16 years after they were first requested. A clear reason for the delay was not provided, but it likely had to do with performance.

该功能现已在 javac 中实现,带有de-糖化"过程;case 声明中使用String 常量的干净、高级语法在编译时扩展为遵循模式的更复杂的代码.生成的代码使用一直存在的 JVM 指令.

The feature has now been implemented in javac with a "de-sugaring" process; a clean, high-level syntax using String constants in case declarations is expanded at compile-time into more complex code following a pattern. The resulting code uses JVM instructions that have always existed.

带有 String 情况的 switch 在编译期间被转换为两个开关.第一个将每个字符串映射到一个唯一的整数——它在原始开关中的位置.这是通过首先打开标签的哈希码来完成的.相应的情况是测试字符串相等性的 if 语句;如果散列上存在冲突,则测试是级联if-else-if.第二个开关反映了原始源代码中的那个,但用它们对应的位置替换了案例标签.这个两步过程可以很容易地保留原始交换机的流量控制.

A switch with String cases is translated into two switches during compilation. The first maps each string to a unique integer—its position in the original switch. This is done by first switching on the hash code of the label. The corresponding case is an if statement that tests string equality; if there are collisions on the hash, the test is a cascading if-else-if. The second switch mirrors that in the original source code, but substitutes the case labels with their corresponding positions. This two-step process makes it easy to preserve the flow control of the original switch.

有关 switch 的更多技术深度,您可以参考 JVM 规范,其中 switch 语句的编译 进行了描述.简而言之,有两种不同的 JVM 指令可用于切换,具体取决于案例使用的常量的稀疏性.两者都依赖于对每种情况使用整数常量来有效执行.

For more technical depth on switch, you can refer to the JVM Specification, where the compilation of switch statements is described. In a nutshell, there are two different JVM instructions that can be used for a switch, depending on the sparsity of the constants used by the cases. Both depend on using integer constants for each case to execute efficiently.

如果常量是密集的,它们被用作指令指针表中的索引(在减去最小值之后)——tableswitch 指令.

If the constants are dense, they are used as an index (after subtracting the lowest value) into a table of instruction pointers—the tableswitch instruction.

如果常量是稀疏的,则执行对正确情况的二分搜索——lookupswitch 指令.

If the constants are sparse, a binary search for the correct case is performed—the lookupswitch instruction.

在对 String 对象上的 switch 去糖化时,可能会使用这两个指令.lookupswitch 适用于第一次打开哈希码以找到案例的原始位置.生成的序数自然适合 tableswitch.

In de-sugaring a switch on String objects, both instructions are likely to be used. The lookupswitch is suitable for the first switch on hash codes to find the original position of the case. The resulting ordinal is a natural fit for a tableswitch.

这两条指令都要求在编译时对分配给每个 case 的整数常量进行排序.在运行时,虽然tableswitchO(1)性能通常比O(log(n))性能好查找开关,它需要一些分析来确定表是否足够密集以证明空间-时间权衡是合理的.Bill Venners 撰写了一篇很棒的文章,其中更详细地介绍了这一点,以及-hood 查看其他 Java 流控制指令.

Both instructions require the integer constants assigned to each case to be sorted at compile time. At runtime, while the O(1) performance of tableswitch generally appears better than the O(log(n)) performance of lookupswitch, it requires some analysis to determine whether the table is dense enough to justify the space–time tradeoff. Bill Venners wrote a great article that covers this in more detail, along with an under-the-hood look at other Java flow control instructions.

在 JDK 7 之前,enum 可以近似基于 String 的开关.这使用 静态 编译器在每个 enum 类型上生成的 valueOf 方法.例如:

Prior to JDK 7, enum could approximate a String-based switch. This uses the static valueOf method generated by the compiler on every enum type. For example:

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}

这篇关于为什么我不能在字符串上使用 switch 语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆