目录
Switch语句长啥样?
Switch支持字符以及字符串的底层原理
为什么不支持long类型呢?
Switch语句长啥样?
public static void main(String[] args) {
int num = 1;
switch (num) {
case 1:
System.out.println("a");
break;
case 2:
System.out.println("b");
break;
default:
System.out.println("c");
}
}
JDK7之前支持的类型只有byte、short、char、int、integer、enum类型。而在JDK7时终于对字符串类型进行了适配。
Switch支持字符以及字符串的底层原理
对于如下这段代码,对其进行反编译
public class SwitchTest {
public static void main(String[] args) {
char ch = 'a';
switch (ch) {
case 'a':
System.out.println("a");
break;
case 'b':
System.out.println("b");
break;
default:
System.out.println("c");
}
String str = "a";
switch (str) {
case "a":
System.out.println("a");
break;
case "b":
System.out.println("b");
break;
default:
System.out.println("c");
}
}
}
反编译代码如下:
public class SwitchTest {
public SwitchTest() {
}
public static void main(String[] args) {
char ch = 97;
switch (ch) {
case 97:
System.out.println("a");
break;
case 98:
System.out.println("b");
break;
default:
System.out.println("c");
}
switch ("a") {
case "a":
System.out.println("a");
break;
case "b":
System.out.println("b");
break;
default:
System.out.println("c");
}
}
}
可以看到对于字符类型来说,底层实际上比较的是 ascii 码,编译器会把char型变量转换成对应的 int 型变量。但发现字符串类型没有变化,难不成是完美适配?【不存在的,仅仅是因为博主的idea或者是jdk版本的问题没有看到它的真实面貌】
借用其它博主的case,代码如下:
public class switchDemoString {
public static void main(String[] args) {
String str = "world";
switch (str) {
case "hello":
System.out.println("hello");
break;
case "world":
System.out.println("world");
break;
default:
break;
}
}
}
上述反编译后如下所示:
public class switchDemoString
{
public switchDemoString()
{
}
public static void main(String args[])
{
String str = "world";
String s;
switch((s = str).hashCode())
{
default:
break;
case 99162322:
if(s.equals("hello"))
System.out.println("hello");
break;
case 113318802:
if(s.equals("world"))
System.out.println("world");
break;
}
}
}
这下可以知道原来字符串的 switch 是通过 equals() 和 hashCode() 方法来实现的。请记住,switch中只能使用整型,比如byte、short、char 以及 int。仔细看下可以发现,switch 块中实际是哈希值,然后通过使用 equals 方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。因此它的性能是不如使用枚举进行 switch 或者使用纯整数常量。Java编译器只增加了一个 equals 方法,如果你比较的是字符串字面量的话会非常快,比如”abc” ==”abc”。如果你把 hashCode() 方法的调用也考虑进来了,那么还会再多一次的调用开销。因为字符串一旦创建了,它就会把哈希值缓存起来。因此如果这个 switch 语句是用在一个循环里的,比如逐项处理某个值,或者游戏引擎循环地渲染屏幕,这里hashCode()方法的调用开销其实不会很大。
为什么不支持long类型呢?
在 stackoverflow 网站上也有人提出同样的问题
挑选出热度最高的评论
大致意思是,因为 switch 的设计初衷是对那些只有少数的几个值进行等值判断,如果值过于复杂,那么还是用 if 比较合适。