看一段代码,这是一道试题,思考一下,结果是什么?为什么?
package cn.com.suntree.utils.myself;
public class SwitchTest {
    public static void main(String[] args) {
        String paramStr = null;
        switch (paramStr){
            case "boy":
                break;
            case "girl":
                System.out.println("is a girl ");
                break;
            case "null":
                System.out.println("is a null ");
                break;
            default:
                System.out.println("is a nothing ");
        }
    }
}我们知道,在jdk1.7之前,switch只接收一个整型表达式,后面扩展了,支持字符串
怎么做到的,由于switch不是方法,没法直接看源码,我们将代码反编译来看看
找到字节码所在文件,用java自带命令
javap -c SwitchTest >switch.dcmp
 获取到反编译代码
Compiled from "SwitchTest.java"
public class cn.com.suntree.utils.myself.SwitchTest {
  public cn.com.suntree.utils.myself.SwitchTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: aconst_null
       1: astore_1
       2: aload_1
       3: astore_2
       4: iconst_m1
       5: istore_3
       6: aload_2
       7: invokevirtual #2                  // Method java/lang/String.hashCode:()I
      10: lookupswitch  { // 3
                 97740: 44
               3173020: 58
               3392903: 72
               default: 83
          }
      44: aload_2
      45: ldc           #3                  // String boy
      47: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      50: ifeq          83
      53: iconst_0
      54: istore_3
      55: goto          83
      58: aload_2
      59: ldc           #5                  // String girl
      61: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      64: ifeq          83
      67: iconst_1
      68: istore_3
      69: goto          83
      72: aload_2
      73: ldc           #6                  // String null
      75: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      78: ifeq          83
      81: iconst_2
      82: istore_3
      83: iload_3
      84: tableswitch   { // 0 to 2
                     0: 112
                     1: 115
                     2: 126
               default: 137
          }
     112: goto          145
     115: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
     118: ldc           #8                  // String is a girl
     120: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     123: goto          145
     126: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
     129: ldc           #10                 // String is a null
     131: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     134: goto          145
     137: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
     140: ldc           #11                 // String is a nothing
     142: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     145: return
}指令看不懂没关系,能看懂这句就行
 也就是说,虽然switch能接收String字符串,但在jvm的实现时,还是取了字符串的hashCode来进行操作
字符串的hashCode方法
 它返回的还是一个int类型的整数,委婉的转换成了int
所以回到问题,我们的paramStr为null对象,那自然在做 hashCode()是会报空指针异常
运行一下结果,完全符合预期

 所以关于switch接收字符串能运行的原因,你明白了吗?
                
                










