Java7中的switch...case支持string的实现细节
2015-10-19 15:42
381 查看
在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,呼吁很久的string支持也终于被加上了。
例如,下面是一段switch中使用string的示例代码。
在switch语句中,string的比较用的是String.equals(),因此大家可以放心的使用。
需要注意的是,传给switch的string变量不能为null,同时switch的case子句中使用的字符串也不能为null。
为什么要有这些非null的限制呢?其实,我们只要将这段代码反汇编出来,看一下底层到底是如何实现的,就可以明白了。下面是汇编出来的代码。
估计有些同学懒得看这些汇编,其实把上面的汇编代码用Java写出来就是下面的样子了。
写到这里,大家应该能明白为什么不能用null了吧。
如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。
如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。
switch支持string只是一个语法糖,由javac来负责生成相应的代码。底层的jvm在switch上并没有进行修改。
转载来源:http://blog.iamzsx.me/show.html?id=161001
参考文献:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
例如,下面是一段switch中使用string的示例代码。
public class Test { public void test(String str) { switch (str) { case "abc": System.out.println("abc"); break; case "def": System.out.println("def"); break; default: System.out.println("default"); } } }
在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了吧。
public class Test { public void test(String str) { int i = -1; switch (str.hashCode()) { case 96354: // "abc".hashCode() if (str.equals("abc")) { i = 0; } break; case 99333: // "def".hashCode() if (str.equals("def")) { i = 1; } break; default: break; } switch (i) { case 0: System.out.println("abc"); break; case 1: System.out.println("def"); break; default: System.out.println("default"); } } }
如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。
如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。
switch支持string只是一个语法糖,由javac来负责生成相应的代码。底层的jvm在switch上并没有进行修改。
转载来源:http://blog.iamzsx.me/show.html?id=161001
参考文献:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
相关文章推荐
- Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?
- java 传递参数的两种方式
- Uploadify配置记录以及上传Session丢失问题解决java版
- 【Java基础】继承中的代码块和构造方法的执行顺序探索
- 严重: Error starting static Resources java.lang.IllegalArgumentException
- java中super和this关键字解析
- Java基础知识学习(九)
- eclipse adb 无法启动
- Java设计模式----单例模式(Singleton)
- Java设计模式----单例模式(Singleton)
- java 校验公民身份证有效性
- 关于java内存泄漏
- Struts2-运行流程分析
- c3p0、dbcp数据源在spring的配置
- SpringMVC访问静态页面
- java 中Int和Integer区别以及相关示例
- SpringMVC访问静态页面
- java 函数返回多个函数值
- Spring中Singleton模式的线程安全
- google-perftools 分析JAVA 堆外内存