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: returnpublic 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上并没有进行修改。
新闻热点
疑难解答