这个功能会被放到以后的 Java 版本中吗?
有人可以解释为什么我不能这样做,例如 Java 的技术方式 switch
声明有效吗?
原文由 Alex Beardsley 发布,翻译遵循 CC BY-SA 4.0 许可协议
这个功能会被放到以后的 Java 版本中吗?
有人可以解释为什么我不能这样做,例如 Java 的技术方式 switch
声明有效吗?
原文由 Alex Beardsley 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果您的代码中有一个可以打开字符串的位置,那么最好将字符串重构为可能值的枚举,您可以打开它。当然,您将可以拥有的字符串的潜在值限制为枚举中的值,这可能是需要的,也可能不需要。
当然,您的枚举可能有一个“其他”条目和一个 fromString(String) 方法,那么您可以
ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
case MILK: lap(); break;
case WATER: sip(); break;
case BEER: quaff(); break;
case OTHER:
default: dance(); break;
}
原文由 JeeBee 发布,翻译遵循 CC BY-SA 2.5 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
带有
String
案例的 Switch 语句已在 Java SE 7 中实现,距 首次请求至少 16 年。 没有提供延迟的明确原因,但这可能与性能有关。JDK 7 中的实现
该功能现已在
javac
中实现, 并带有“脱糖”过程; 使用String
常量的干净的高级语法case
声明在编译时扩展为遵循模式的更复杂的代码。生成的代码使用一直存在的 JVM 指令。A
switch
和String
案例在编译期间被翻译成两个开关。第一个将每个字符串映射到一个唯一的整数——它在原始开关中的位置。这是通过首先打开标签的哈希码来完成的。对应的case是一个测试字符串相等性的if
语句;如果哈希上存在冲突,则测试是级联if-else-if
。第二个开关反映了原始源代码中的那个,但是用它们的相应位置替换了 case 标签。这个两步过程可以很容易地保留原始交换机的流量控制。JVM 中的开关
关于
switch
的更多技术深度,您可以参考 JVM 规范,其中描述 了 switch 语句的编译。简而言之,有两种不同的 JVM 指令可用于开关,具体取决于案例使用的常量的稀疏性。两者都依赖于为每种情况使用整数常量才能有效执行。如果常量是密集的,它们将用作指令指针表中的索引(在减去最低值之后)
tableswitch
指令。如果常量是稀疏的,则执行对正确大小写的二进制搜索
lookupswitch
指令。在对
switch
对String
对象进行脱糖时,可能会使用这两条指令。lookupswitch
适用于第一次打开hash码找到case的原始位置。生成的序号自然适合tableswitch
。这两条指令都需要在编译时对分配给每种情况的整数常量进行排序。 At runtime, while the
O(1)
performance oftableswitch
generally appears better than theO(log(n))
performance oflookupswitch
, it requires some analysis to determine whether该表足够密集以证明时空权衡是合理的。 Bill Venners 写 了一篇很棒的文章,更详细地介绍了这一点,并深入了解了其他 Java 流控制指令。在 JDK 7 之前
在 JDK 7 之前,
enum
可以近似于基于String
的开关。这使用编译器在每个enum
类型上生成 的静态valueOf
方法。例如: