Java7中的switch支持String的实现细节
来源:互联网 发布:淘宝服装试用报告范文 编辑:程序博客网 时间:2024/05/16 04:28
Java7中的switch支持String的实现细节
在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,呼吁很久的String支持也终于被加上了。
例如,下面是一段switch中使用String的示例代码。
1 public class Test { 2 3 public void test(String str) { 4 switch(str) { 5 case "abc": 6 System.out.println("abc"); 7 break; 8 case "def": 9 System.out.println("def");10 break;11 default:12 System.out.println("default");13 }14 }15 16 }
在switch语句中,String的比较用的是String.equals,因此大家可以放心的使用。
需要注意的是,传给switch的String变量不能为null,同时switch的case子句中使用的字符串也不能为null。
为什么要有这些非null的限制呢?其实,我们只要将这段代码反汇编出来,看一下底层到底是如何实现的,就可以明白了。下面是汇编出来的代码。
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public void test(java.lang.String);
Code:
0: aload_1
1: astore_2
2: iconst_m1
3: istore_3
4: aload_2
5: invokevirtual #2; //Method java/lang/String.hashCode:()I
8: lookupswitch{ //2
96354: 36;
99333: 50;
default: 61 }
36: aload_2
37: ldc #3; //String abc
39: invokevirtual #4; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
42: ifeq 61
45: iconst_0
46: istore_3
47: goto 61
50: aload_2
51: ldc #5; //String def
53: invokevirtual #4; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
56: ifeq 61
59: iconst_1
60: istore_3
61: iload_3
62: lookupswitch{ //2
0: 88;
1: 99;
default: 110 }
88: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
91: ldc #3; //String abc
93: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
96: goto 118
99: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
102: ldc #5; //String def
104: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
107: goto 118
110: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
113: ldc #8; //String default
115: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
118: return
}
估计有些同学懒得看这些汇编,其实把上面的汇编代码用Java写出来就是下面的样子了。
写到这里,大家应该能明白为什么不能用null了吧。
1 public class Test { 2 public void test(String str) { 3 int i = -1; 4 switch(str.hashCode()) { 5 case 96354: // "abc".hashCode() 6 if (str.equals("abc")) { 7 i = 0; 8 } 9 break;10 case 99333: // "def".hashCode()11 if (str.equals("def")) {12 i = 1;13 }14 break;15 default:16 break;17 }18 19 switch(i) {20 case 0:21 System.out.println("abc");22 break;23 case 1:24 System.out.println("def");25 break;26 default:27 System.out.println("default");28 }29 }30 }
如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。
如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。
switch支持String只是一个语法糖,由javac来负责生成相应的代码。底层的JVM在switch上并没有进行修改。
参考
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。
如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。
switch支持String只是一个语法糖,由javac来负责生成相应的代码。底层的JVM在switch上并没有进行修改。
从上面的代码中可以看出,原来用在 switch 语句中的字符串被替换成了对应的哈希值,而 case 子句的值也被换成了原来字符串常量的哈希值。经过这样的转换,Java 虚拟机所看到的仍然是与整数类型兼容的类型。在这里值得注意的是,在 case 子句对应的语句块中仍然需要使用 String 的 equals 方法来进行字符串比较。这是因为哈希函数在映射的时候可能存在冲突,多个字符串的哈希值可能是一样的。进行字符串比较是为了保证转换之后的代码逻辑与之前完全一样。
0 0
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch...case支持string的实现细节
- Java7中的switch支持String的实现细节
- Java7中的switch支持String的实现细节
- Java7中switch支持String
- Java7中Switch支持String
- Java7中Switch语句支持String
- Java 7 switch支持String类型的原理和关于switch一些细节
- java7 语法糖 之 switch 语句中的string
- 安卓基础回调~以及关于部分直播录制压缩问题
- poi 操作excel的样式
- struts2文件上传设置上传文件类型
- B
- 热浪
- Java7中的switch支持String的实现细节
- 基于Vue2.0+Vuex+Axios+NodeJs+Express+MySQL实现京东移动web商城
- 堆栈
- Harmonic Number (II)
- MOL3D
- 永磁电机直轴交轴理解
- 深入了解volatile
- 手动内存管理方法
- No.7_3 OpenCL 同步——事件同步