Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
334 views
in Technique[技术] by (71.8m points)

java - 为什么不能在字符串上使用switch语句?(Why can't I use switch statement on a String?)

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

(此功能是否将在以后的Java版本中使用?)

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

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

  ask by Alex Beardsley translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Switch statements with String cases have been implemented in Java SE 7 , at least 16 years after they were first requested.

(带有String switch语句已在Java SE 7中实现 ,至少在首次提出要求后的 16年)

A clear reason for the delay was not provided, but it likely had to do with performance.

(没有提供延迟的明确原因,但可能与性能有关。)

Implementation in JDK 7 (在JDK 7中实现)

The feature has now been implemented in javac with a "de-sugaring" process;

(现在,该功能已通过javac 中的“反糖化”过程实现。)

a clean, high-level syntax using String constants in case declarations is expanded at compile-time into more complex code following a pattern.

(在case声明中使用String常量的一种干净的高级语法在编译时扩展为遵循模式的更复杂的代码。)

The resulting code uses JVM instructions that have always existed.

(生成的代码使用始终存在的JVM指令。)

A switch with String cases is translated into two switches during compilation.

(在编译过程中,具有Stringswitch将转换为两个开关。)

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语句,用于测试字符串是否相等;)

if there are collisions on the hash, the test is a cascading if-else-if .

(如果哈希上有冲突,则测试为级联的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.

(此两步过程使保留原始交换机的流量控制变得容易。)

Switches in the JVM (在JVM中切换)

For more technical depth on switch , you can refer to the JVM Specification, where the compilation of switch statements is described.

(有关switch更多技术深度,可以参考JVM规范,其中描述了switch语句编译 。)

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.

(简而言之,有两种不同的JVM指令可用于切换,具体取决于案例使用的常量的稀疏性。)

Both depend on using integer constants for each case to execute efficiently.

(两者都依赖于每种情况下使用整数常量来有效执行。)

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.

(如果常量是密集的,则将它们用作指令指针表( tableswitch指令)的索引(减去最小值后)。)

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

(如果常量稀疏,则执行二进制搜索以lookupswitch正确的大小写lookupswitch指令。)

In de-sugaring a switch on String objects, both instructions are likely to be used.

(在对String对象的switch进行除糖处理时,很可能会使用这两个指令。)

The lookupswitch is suitable for the first switch on hash codes to find the original position of the case.

(lookupswitch适用于哈希码的第一个开关,以查找案例的原始位置。)

The resulting ordinal is a natural fit for a tableswitch .

(产生的序数自然适用于tableswitch 。)

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.

(在运行时,而O(1)性能tableswitch一般都比较好显得比O(log(n))的性能lookupswitch ,它需要一些分析,以确定该表是否是密集足以证明时空权衡。)

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.

(Bill Venners写了一篇很棒的文章 ,其中更详细地介绍了此内容,同时还深入介绍了其他Java流程控制指令。)

Before JDK 7 (在JDK 7之前)

Prior to JDK 7, enum could approximate a String -based switch.

(在JDK 7之前, enum可以近似于基于String的开关。)

This uses the static valueOf method generated by the compiler on every enum type.

(这将使用编译器针对每种enum类型生成的静态valueOf方法。)

For example:

(例如:)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...