Switch能否用String做参数?
参数可以是整数表达式,JDK1.5开始支持Enum类,JDK1.7开始支持String。
当字符串不会频繁改变时可以用枚举来代替String:用Enum.parse。
注意:
1.JDK1.6 的版本中,switch后面的括号里面只能放int类型的值,注意是只能放int类型,但是放byte,short,char类型的也可以。是因为byte,short,char可以自动提升(自动类型转换)为int。而不能放long型和String型。
JDK1.7 的版本中,switch中可以使用字串String。但仍不支持long型。
2.String时不能传入null作为参数,同时case语句中使用的字符串也不能为null,因为底层是通过equals和hashmap来判断的
原理:hashCode()+equals()
编译器在编译期间给代码做了转换。
- public enum Weekend
- {
- Monday,
- Tuesday,
- Friday,
- }
-
- public void Test(string week)
- {
- Weekend weekend = (Weekend)Enum.Parse(typeof(Enum), week, false);
-
- switch (weekend)
- {
- case Weekend.Monday:
- Console.WriteLine("Today is Monday");
- break;
- case Weekend.Tuesday:
- Console.WriteLine("Today is Tuesday");
- break;
- case Weekend.Friday:
- Console.WriteLine("Today is Friday");
- break;
- default:
- break;
- }
- }
- </pre><pre name="code" class="javascript">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");
- }
- }
-
- }
反编译后的结果:
- public class Test {
- public void test(String str) {
- int i = -1;
- switch(str.hashCode()) {
- case 96354:
- if (str.equals("abc")) {
- i = 0;
- }
- break;
- case 99333:
- 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");
- }
- }
- }
PS
:hashcode返回的是int型
可以发现:进行switch的实际是hash值,然后用equals进行安全检查(因为hash值可能会发生碰撞),所以性能不如枚举。switch支持String其实是一个语法糖,在编译后的字节码文件中都会被还原成原生类型,并在相应位置插入了强制转换代码,底层的JVM在switch上并没有修改。
当传入switch的是null时,在运行时对一个null调用hashCode()方法,会抛出NullPointerException;如果case写的是null,那么在编译时无法求出hashcode,就会编译报错。