Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5bb65f7

Browse files
author
sunwne
committed
为什么不能用string作为switch的case
1 parent 88d1c32 commit 5bb65f7

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Why can't I switch on a String
2+
3+
##问题描述
4+
为什么不能用string类型进行switch判断?
5+
是否作为一个功能将会被添加如java后续版本中?
6+
有人能给我一篇文章,或者解释一下为什么不能这样做,说明java中switch语句的运行方式?
7+
8+
##回答
9+
用string作为case来使用switch语句已经在java SE7中被实现了,距离这个问题被提出至少有16年了。一个明确的原因迟迟未提供,但是性能要求它必须这样做。
10+
11+
**Implementtation in JDK 7**
12+
这个特性现在已经被实现,`javac`with a ["de-sugaring peocess"](http://blogs.oracle.com/darcy/entry/project_coin_string_switch_anatomy)。一个高级的,清楚的使用String常量的语法能在case声明中被使用,会在编译时扩展成为更复杂的代码模式,生成的代码使用jvm指令也一直存在。
13+
switch将string用作case在编译时翻译成两个switch。第一次每一个string映射到一个独一无二的整数,它的位置在原始的switch上。这是通过在case上的hashcode进行switch选择,相应的案例是一个if语句,测试字符串是否相等。如果有哈希碰撞,测试就像`if-else-if`
14+
第二次switch反映在最初的源代码中,用相应位置上的整数代替响应的string标签case。这两步过程更容易保留原始switch的流程控制。
15+
16+
**Switchs in the JVM**
17+
在switch的更多深层技术上,可以参考JVM规范,[compliation of switch statements](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.10)有响应的描述。简单概括说,根据使用的常量的多少,switch有两种不同的JVM指令来执行,每种情况下都取决于使用整数常量来有效的执行。
18+
19+
如果常量很多,case会在一个指令表被用作索引(减去最小值后)——`tablewitch`指令
20+
如果常量相对较少,那么可用二分查找来找到正确的case--`lookupswitch`指令
21+
22+
`de-sugaring`中,一个switch(String)的对象,两种指令都会被用到。`lookupswitch`指令适用于第一次计算哈希值找到初始位置,由此产生的顺序表很自然的用`tableswitch`指令
23+
24+
两种指令在编译时都需要将整数常量赋值给每个case。在运行时,虽然`tableswitch`O(1)的性能通常要好于`lookupswitch`O(log(n))的性能,但是前者需要一定的分析来决定是否有足够的case来满足时间空间的平衡。Bill Venners的文章[a great article](http://www.artima.com/underthehood/flowP.html)在细节上讲述的更多,以及涉及到从底层的出发,来看其他java流程控制指令。
25+
26+
**Before JDK 7**
27+
在JDK之前,枚举近似的用String作为switch的case,这使用了静态方法`valueOf`,编译器生成了一个枚举类型。例子如下:
28+
```
29+
Pill p = Pill.valueOf(str);
30+
switch(p) {
31+
case RED:pop();break;
32+
case BLUE:push();break;
33+
}
34+
```
35+
36+
[阅读原文:Why can`t I switch on a String](http://stackoverflow.com/questions/338206/why-cant-i-switch-on-a-string)
37+
38+
39+
40+
41+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /