Java switch语句
问题起源:一次使用 switch 没有使用 break 引起了生产上 bug 后(switch-break 还是需要注意注意在注意),后来想着看看 switch 编译后到底为啥需要 break,单纯的想看看 switch 语句编译后是什么样子。随发现了奇怪的现象,也就是 switch 关于对 String 类型的支持的实现过程。
通过示例分析下 switch 对于 int char 和 String 的支持,其中 String 为 jdk1.7 新特性
-
switch 关于 int 的编译
private void switchInt(Integer i) { switch (i){ case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: } }编译后结果:
private void switchInt(Integer var1) { switch(var1) { case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); } }总结:int 类型的 switch 语句编译前后没有任何区别
-
switch 关于 char 的编译
private void switchChar(char c) { switch (c){ case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: } }编译后结果:
private void switchChar(char var1) { switch(var1) { case '\u0000': System.out.println("0"); break; case '\u0001': System.out.println("1"); break; case '\u0002': System.out.println("2"); } }总结:唯一的编译操作就是将非 char 字符动态转换成 char 字符
-
switch 关于 String 的编译
private void switchString(String s) { switch (s){ case "0": System.out.println("0"); break; case "1": System.out.println("1"); break; case "2": System.out.println("2"); break; default: } }编译后结果:
private void switchString(String var1) { byte var3 = -1; switch(var1.hashCode()) { case 48: if (var1.equals("0")) { var3 = 0; } break; case 49: if (var1.equals("1")) { var3 = 1; } break; case 50: if (var1.equals("2")) { var3 = 2; } } switch(var3) { case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); } }总结:这里就是重点了,jdk7 对于 String 的支持原则上还是基于原jdk对于 int 的支持,将原 string 的比较转换成 hashcode,也就是相当于 int 的类型比较,再将字符串比较放在 case 语句中使用 equals 比较,使用新定义的 int 接收,再使用原生的 switch 语句实现具体操作。这算是转圜这实现了对于 string 的支持了。
引发的新的小问题:char 字符编译前后的区别
示例代码:
private void switchChar(char c) { switch (c){ case 0: System.out.println("0"); break; case '0': System.out.println("12"); break; case ' ': System.out.println("123"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: } }编译后:
private void switchChar(char var1) { switch(var1) { case '\u0000': System.out.println("0"); break; case '\u0001': System.out.println("1"); break; case '\u0002': System.out.println("2"); break; case ' ': System.out.println("123"); break; case '0': System.out.println("12"); } }总结:发现一个奇怪的问题,就是关于 char 的编译,将数字 0 转换成 '\u0000',可是百度一番确看到的都是 空格会被转换成 '\u0000',有点不是很理解,单独拿出来备注下。
// jdk 中关于 Character 的源码中的 '\u0000' /** * The constant value of this field is the smallest value of type * {@code char}, {@code '\u005Cu0000'}. * * @since 1.0.2 */ public static final char MIN_VALUE = '\u0000'; /** * The constant value of this field is the largest value of type * {@code char}, {@code '\u005CuFFFF'}. * * @since 1.0.2 */ public static final char MAX_VALUE = '\uFFFF';关于'\u0000'问题依然没有解决。
` 同时回忆下原生的Java编译,不可忘本。
javac TestDemo.java `